我在汇编中有以下代码(由clang汇编)
更新到我认为会导致对齐的内容;仍然没有。
再次更新;即使有您的建议,代码仍然会出现段错误(感谢 Stephen Canon 的建议)我还尝试减去 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 保存返回地址(从调用中弹出它对吗?),从堆栈中弹出参数并在执行后跳转到保存的 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
然后我将 8 个字节添加到 esp 删除填充所以它看起来像这样
=============== (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的内置汇编器(我认为是gas),然后是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