问题描述
我有一个简单的汇编代码,可以在Mac OS X(x86-64)上正常工作,但不能在Linux(x86-64)上正常工作:
I have a simple piece of assembly code that works correctly on Mac OS X (x86-64) but not on Linux (x86-64):
.data
.align 4
foo: .quad 1,2
.text
.globl fun
fun:
movapd foo(%rip), %xmm1
ret
从一个简单的C程序调用:
Called from a simple C program:
int main(void){
fun();
return 0;
}
在Mac上发生的是xmm1寄存器中的数据位于foo位置,即在GDB中:
What happens on the Mac is that the xmm1 register is filled with the data at location foo i.e. in GDB:
(gdb) p $xmm1
$2 = {
...
v2_int64 = {2, 1},
uint128 = 0x00000000000000020000000000000001
}
当我在Linux下运行相同的代码时,它会出现段错误-似乎foo标签对应于0x0:
When I run the same code under Linux it segfaults - it seems that the foo label corresponds to 0x0:
> objdump -d asm.o
...
Disassembly of section .text:
0000000000000000 <fun>:
0: 66 0f 28 0d 00 00 00 movapd 0x0(%rip),%xmm1
...
有人可以解释为什么会发生这种情况吗?我该怎么做才能避免这种情况发生?
Can someone explain why this occurs and what I can do to avoid it?
欢呼
- 伊恩
推荐答案
在主线gnu binutils上,在i386和x86_64上, .align n
指令告诉汇编器将其对齐为n个字节(但是),在某些架构和平台上,它还有其他含义.有关详细信息,请查阅文档).
On the mainline gnu binutils, on i386 and x86_64, the .align n
directive tells the assembler to align to n bytes (however, on some architectures and platforms, it has other meanings. Consult the documentation for full details).
在OS X上, .align n
指令告诉汇编程序将其对齐为2 ^ n个字节.这就是为什么您的代码可以在Mac上运行的原因.
On OS X, the .align n
directive tells the assembler to align to 2^n bytes. This is why your code works on the Mac.
如果要保持一致的跨平台行为,请改用 .p2align
指令,该指令在两个平台上均受支持,并告诉汇编程序将其对齐为2 ^ n个字节.
If you want consistent cross-platform behavior, use the .p2align
directive instead, which is supported on both platforms, and tells the assembler to align to 2^n bytes.
这篇关于Linux上具有RIP相对寻址的Segfault的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!