1

アセンブリに次のコードがあります(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
4

2 に答える 2