问题描述
我想学写汇编语言64位的Mac OS。我没有问题,32位Mac OS和32位和64位Linux。
I am trying to learn writing assembly language for 64 bit Mac OS. I have no problem with 32 bit Mac OS and both 32 bit and 64 bit Linux.
但是,Mac OS 64位不同的是,我无法弄清楚。所以我在这里寻求帮助。
However, Mac OS 64 bit is different and I couldn't figure out. Therefore I am here to ask for help.
我有没有问题,使用系统调用来打印。不过,我想学习如何调用使用Mac OS的64位汇编语言的C函数。
I have not problem using system call to print. However, I would like to learn how to call C functions using 64 bit assembly language of Mac OS.
请看看下面的code
Please look at the following code
.data
_hello:
.asciz "Hello, world\n"
.text
.globl _main
_main:
movq $0, %rax
movq _hello(%rip), %rdi
call _printf
我用$ GCC -arch x86_64的hello.s
I use$ gcc -arch x86_64 hello.s
装配和连接。
它生成的二进制code。但是,我在运行时,它得到了一个分段错误。
It generates binary code. However, I got a segmentation fault when running it.
我试着像以前一样叫_printf,还是一样的结果之前加入SUBQ $ 8%,可吸入悬浮粒子。
I tried adding "subq $8, %rsp" before calling _printf, still the same result as before.
我做了什么错?
顺便说一句,是没有办法调试Mac上的这个code?我尝试添加-ggdb或-gstab或-gdwarf,和$ GDB ./a.out,并不能看到code和设置断点。
By the way, is that any way to debug this code on Mac? I tried adding -ggdb or -gstab or -gDWARF, and$gdb ./a.out, and can't see the code and set break points.
推荐答案
您没有说什么,你所看到的问题是,但我猜你崩溃的调用点到的printf
。这是因为OS X(32位和64位)要求堆栈指针有16字节对齐,在任何外部函数调用的地步。
You didn't say exactly what the problem you're seeing is, but I'm guessing that you're crashing at the point of the call to printf
. This is because OS X (both 32- and 64-bit) requires that the stack pointer have 16-byte alignment at the point of any external function call.
在 _main
被称为堆栈指针是16字节对齐;该呼叫推八字节的返回地址压入堆栈,所以堆栈16字节的调用点对准 _printf
。进行调用,以正确对齐之前减去八名%RSP
。
The stack pointer was 16-byte aligned when _main
was called; that call pushed an eight-byte return address onto the stack, so the stack is not 16-byte aligned at the point of the call to _printf
. Subtract eight from %rsp
before making the call in order to properly align it.
所以,我继续和调试这个给你(没有魔法参与其中,只使用GDB,打破主
,显示/ 5I $ PC
, STEPI
等)。您遇到的另一个问题是在这里:
So I went ahead and debugged this for you (no magic involved, just use gdb, break main
, display/5i $pc
, stepi
, etc). The other problem you're having is here:
movq _hello(%rip), %rdi
这加载前八个字节的字符串到%RDI
,这是不是你想要的所有(特别是前八个字节的字符串是极不可能构成一个有效的指针格式字符串,这会导致崩溃的printf
)。相反,你要加载的字符串的地址的。你的程序的调试版本是:
This loads the first eight bytes of your string into %rdi
, which isn't what you want at all (in particular, the first eight bytes of your string are exceedingly unlikely to constitute a valid pointer to a format string, which results in a crash in printf
). Instead, you want to load the address of the string. A debugged version of your program is:
.cstring
_hello: .asciz "Hello, world\n"
.text
.globl _main
_main:
sub $8, %rsp // align rsp to 16B boundary
mov $0, %rax
lea _hello(%rip), %rdi // load address of format string
call _printf // call printf
add $8, %rsp // restore rsp
ret
这篇关于如何用printf写汇编语言的Hello World程序的64位Mac OS X的?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!