簡體   English   中英

Linux 上具有 RIP 相對尋址的段錯誤

[英]Segfault with RIP-relative addressing on Linux

我有一段簡單的匯編代碼,它可以在 Mac OS X (x86-64) 上正常工作,但在 Linux (x86-64) 上卻不能正常工作:

.data
.align 4

foo: .quad 1,2

.text

.globl fun
fun:
movapd foo(%rip), %xmm1
ret

從一個簡單的 C 程序調用:

int main(void){
  fun();
  return 0;
}

在 Mac 上發生的情況是 xmm1 寄存器填充了位置 foo 的數據,即 GDB 中的數據:

(gdb) p $xmm1
$2 = {
...
v2_int64 = {2, 1}, 
uint128 = 0x00000000000000020000000000000001
}

當我在 Linux 下運行相同的代碼時,它會出現段錯誤 - 似乎 foo 標簽對應於 0x0:

> objdump -d asm.o
...

Disassembly of section .text:
0000000000000000 <fun>:
   0:   66 0f 28 0d 00 00 00   movapd 0x0(%rip),%xmm1
...

有人可以解釋為什么會發生這種情況以及我可以做些什么來避免它?

干杯

  • 伊恩

段錯誤是由於未對齊而發生的。 4 字節對齊對於 movapd 來說是不夠的,您至少需要 16 字節.align 16

您會在 objdump 中看到0(%rip) ,因為代碼尚未重新定位。 當您執行它時,運行時鏈接器將用正確的偏移量替換它。

在主線 gnu binutils 上,在 i386 和 x86_64 上, .align n指令告訴匯編器對齊到 n 個字節(但是,在某些體系結構和平台上,它具有其他含義。有關完整詳細信息,請參閱文檔)。

在 OS X 上, .align n指令告訴匯編器對齊到 2^n 字節。 這就是您的代碼在 Mac 上運行的原因。

如果您想要一致的跨平台行為,請改用.p2align指令,該指令在兩個平台上都受支持,並告訴匯編器對齊到 2^n 字節。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM