为什么这个movq指令适用于linux而不是osx?
作者:互联网
以下汇编代码在OSX 10.9.4上运行时出错,但在Linux上运行成功(Debian 7.6).特别是,movq指令似乎不喜欢label参数.
$cat test.S
.globl _main
_main:
movq $_main, %rax
ret
这是错误:
$as -o test.o test.S
test.S:3:32-bit absolute addressing is not supported for x86-64
test.S:3:cannot do signed 4 byte relocation
将第3行中的$_main更改为像$10这样的文字可以正常工作.
代码必须以非常小的方式进行修改才能在Linux上运行 – 只需从标签中删除下划线即可.
$cat test.S
.globl main
main:
movq $main, %rax
ret
很容易独立验证代码在Linux上是否可行:
$as -o test.o test.S
$gcc -o test.out test.o
$./test.out
请忽略代码并没有真正做很多事情,我故意尽可能地将其修剪下来以证明错误.
我已经看了很多使用LEA(加载有效地址),但在我做出改变之前,我想了解其中的区别 – 为什么它适用于Linux而不是OSX?
解决方法:
你对movq指令无法引用绝对地址是正确的.这部分是由于OS X ABI Mach-O格式使用了可重定位的符号寻址.
编译为与位置无关的可执行文件(PIE)的程序通常不能以与movq $_main,%rax相同的方式引用绝对虚拟地址.而是调用Global Offset Tables,其允许位置相对代码(PC-rel)和位置无关代码(PIC)在其当前绝对地址位置处提取全局符号.如下所示,GOTPCREL(%rip)创建了lea rdi,_msg的解释:
PC-rel代码引用它的全局偏移表:
.globl _main
_main:
movq _main@GOTPCREL(%rip), %rax
sub $8, %rsp
mov $0, %rax
movq _msg@GOTPCREL(%rip), %rdi
call _printf
add $8, %rsp
ret
.cstring
_msg:
.ascii "Hello, world\n"
Mac OS X Mach-O汇编程序:
$as -o test.o test.asm
Apple的GCC版本:
$gcc -o test.out test.o
输出:
$./test.out
Hello, world
标签:linux,x86-64,macos 来源: https://codeday.me/bug/20191006/1861506.html