为什么此movq指令在Linux而不是osx上有效? [英] Why does this movq instruction work on linux and not osx?

查看:157
本文介绍了为什么此movq指令在Linux而不是osx上有效?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在OSX 10.9.4上运行as时,以下汇编代码给出了错误,但在Linux(Debian 7.6)上成功运行.特别是,movq指令似乎不喜欢label参数.

The following assembly code gives an error when running as on OSX 10.9.4, but works successfully on Linux (Debian 7.6). In particular, the movq instruction doesn't seem to like the label argument.

$ 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的文字可以正常工作.

Changing $_main in line 3 to a literal like $10 works fine.

必须以非常小的方式修改代码才能使其在Linux上运行-只需从标签中删除下划线即可.

The code had to be modified in a very minor way to get it to run on Linux - by simply removing the underscores from the labels.

$ cat test.S
.globl main
main:
    movq $main, %rax
    ret

独立验证代码是否可以在Linux上运行很容易:

It's pretty easy to independently verify that the code does work on Linux:

$ as -o test.o test.S
$ gcc -o test.out test.o
$ ./test.out

请忽略该代码实际上并没有执行任何操作,我特意将其尽可能地缩小以展示该错误.

Please ignore that the code doesn't really do much of anything, I've intentionally trimmed it down as much as possible to demonstrate the error.

我已经考虑使用LEA(有效负载地址)了很多,但是在进行更改之前,我想了解一下这种区别-为什么它可以在Linux而不是OSX上运行?

I've looked quite a bit into using LEA (load effective address), but before I make that change I'd like to understand the difference - why does it work on Linux and not OSX?

推荐答案

关于movq指令不能引用绝对地址的信息,您是正确的.这部分是由于 OS X ABI Mach-O 格式,该格式使用可重定位符号.

You are correct about the movq instruction not being able to reference the absolute address. This is in part due to the OS X ABI Mach-O format which uses relocatable addressing for symbols.

被编译为与位置无关的可执行文件(PIE)的程序通常不能以与movq $_main, %rax相同的方式引用绝对虚拟地址.而是 全局偏移表 被调用,这允许位置相对代码(PC-rel)和位置独立代码(PIC)在其位置提取全局符号当前的绝对地址位置.如下所示,GOTPCREL(%rip)创建了对lea rdi, _msg的解释:

A Program that is compiled as a position-independent executable (PIE) generally cannot reference an absolute virtual address in the same manner as movq $_main, %rax does. Instead, Global Offset Tables are called upon, which allow position relative code (PC-rel) and position-independent code (PIC) to extract global symbols at their current absolute address location. Demonstrated below, GOTPCREL(%rip)creates an interpretation of lea rdi, _msg:

引用其全局偏移表的PC相关代码:

.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

这篇关于为什么此movq指令在Linux而不是osx上有效?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆