我正在研究http://www.ibm.com/developerworks/linux/library/l-gas-nasm/index.html上的一些教程,以熟悉x86/x64。本教程代码使用提供的使用AT&T语法的代码进行编译和运行,不会出现打h的情况:
.global main
.text
main: # This is called by C library's startup code
mov $message, %rdi # First integer (or pointer) parameter in %edi
call puts # puts("Hello, World")
ret # Return to C library code
message:
.asciz "Hello, World" # asciz puts a 0x00 byte at the end
但是,当我将此代码转换为Intel语法时,出现“Segmentation fault”错误。
.intel_syntax noprefix
.global main
.text
main: # This is called by C library's startup code
mov rdi, message # First integer (or pointer) parameter in %edi
call puts # puts("Hello, World")
ret # Return to C library code
message:
.asciz "Hello, World" # asciz puts a 0x00 byte at the end
我对x86不熟悉,所以也许我缺少了一些东西。有任何想法吗?
最佳答案
在AT&T语法中,mov $message, %rdi
,$
表示立即数,表示消息的地址。
在GAS的Intel语法中,mov rdi, message
表示绝对寻址,即消息中的内容。要获取消息的实际地址,您需要提供offset
关键字:mov rdi, offset message
。
取消对两个二进制文件的区别表明了它们的区别:
AT&T:
0000000000000000 <main>:
0: 48 c7 c7 00 00 00 00 mov $0x0,%rdi
英特尔:0000000000000000 <main>:
0: 48 8b 3c 25 00 00 00 00 mov 0x0,%rdi
关于assembly - 为什么从AT&T切换到Intel语法会使本教程使用GAS出现段错误?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16121173/