アセンブリに次のコードがあります(clangによってアセンブルされます)
調整を引き起こすと思われるものに更新しました。まだありません。
再度更新; あなたの提案があっても、コードはまだセグフォルトです(スティーブンキャノンの提案に感謝します)また、4、8、12を減算しようとしましたが、同じスタックの再調整の問題で機能しませんでした。詳細情報が更新されました。
.globl _main
.data
_hw: .asciz "Hello World\n\0"
.text
_main:
push 8 # 4 bytes
push _hw # 4 bytes
push 0 # 4 bytes
##https://developer.apple.com/library/mac/documentation/CoreFoundation/Reference/CFStringRef/Reference/reference.html#//apple_ref/c/func/CFStringCreateWithCString
call _CFStringCreateWithCString # 4 bytes
## push CFSTR return value in eax
sub esp, 8 # 8 bytes
push eax # 4 bytes
##https://developer.apple.com/library/ios/DOCUMENTATION/CoreFoundation/Reference/CFTypeRef/Reference/reference.html#//apple_ref/c/func/CFShow
call _CFShow # 4 bytes
add esp, 8 # remove padding from stack pointer
mov eax, 99
ret
プログラムの実行
メイン スタックの先頭が空です
=============== (0xFFFF)
| |
| STACK |
| |
===============
8、_hw のアドレス、および 0 をプッシュしてから、_CFStringCreateWithCString を呼び出します。今は次のように見えます
=============== (0xFFFF)
| 8 |
|-------------- (0xFFFB) 4 bytes for 8
| hw address |
|-------------- (0xFFF7) 4 bytes for address of hw
| 0 |
|-------------- (0xFFF3) 4 bytes for 0 (NULL)
| call |
--------------- (0xFFEF) 4 bytes for address to return to after call (eip?) Is this 8 on x64?
次に、CFStringCreateWithCString が呼び出され、戻りアドレスを保存し (call correct? からポップします)、スタックから引数をポップし、実行後に保存された eip アドレスにジャンプして、その戻り値を eax に入れます。
その後、スタックは次のようになります
=============== 0xFFFF
| |
| STACK |
| |
===============
次に、esp から 8 を引くと、次のようになります。
=============== (0xFFFF)
| Padding |
| 8 bytes |
|-------------- (0xFFF7) (esp)
| |
===============
次に、CFStringCreateWithCString から eax をプッシュして、スタックが次のようになるようにします。
=============== (0xFFFF)
| Padding |
| 8 bytes |
|-------------- (0xFFF7) # 8 bytes padding from subtracting the stack counter
| eax |
|-------------- (0xFFF3) # 4 bytes from eax, the return from last call, or is it 8 bytes on x64?
| call |
|-------------- (0xFFEF) # 4 bytes to return after call (eip?)
===============
CFShow への呼び出し (および呼び出しからの引数とアドレスのポップオフ) の後、スタックは次のようになります。
=============== (0xFFFF)
| Padding |
| 8 bytes |
|-------------- (0xFFF7) # 8 bytes padding from subtracting the stack counter, CFShow doesn't touch this as it only expects 4 byte address
次に、パディングを削除して esp に 8 バイトを追加すると、次のようになります。
=============== (0xFFFF)
| |
| STACK |
| |
===============
正しい?
これは、コードを実行するために入力したものです。プロセッサが 64 ビットであるため、何かを変更する必要がありますか?
MacBookPro:HelloWorld user$ cat hand.s
.globl _main
.data
_hw: .asciz "Hello World\n\0"
.text
_main:
push 8 # 4 bytes
push _hw # 4 bytes
push 0 # 4 bytes
call _CFStringCreateWithCString
## push CFSTR return value in eax
sub esp, 8 # 8 bytes
push eax # 12 bytes
call _CFShow
mov eax, 99
ret
私のコンパイル手順は、clang の組み込みアセンブラー (ガスだと思います) を使用してから、ld. これは Mac OS X 64 ビット Mountain Lion 上にあります。
MacBookPro:HelloWorld user$ clang -cc1as -filetype obj -mllvm --x86-asm-syntax=intel -o hand.o hand.s
CoreFoundation とリンクする
MacBookPro:HelloWorld user$ ld -macosx_version_min 10.8.0 -o hand hand.o -lSystem -framework CoreFoundation
実行可能ファイルを実行します。
MacBookPro:HelloWorld user$ ./hand
Segmentation fault: 11
MacBookPro:HelloWorld user$
次のエラーが発生します
Segmentation fault: 11