理解汇编语言中的.long指令

3
在 John Viega 的《安全编程 C 和 C++ 秘籍》中,我遇到了以下陈述。
asm("value_stored:    \n"
    ".long 0xFFFFFFFF \n"
);

我不太理解汇编中.long指令的用途,但它被用于将预先计算的值嵌入可执行文件中。我能否以某种方式强制这些字节在可执行文件中的位置?我尝试将其放在main结尾(认为这样会在.text段的末尾),但出现了分段错误。将其放在main外部可以。


在C语言中,您可以使用long value_stored = 0xFFFFFFFF;来实现相同的效果。 - UmNyobe
1
@UmNyobe:完全不是同一回事。只要按照AkiSuihkonen的解释跳过它,static unsigned long const value_stored = 0xFFFFFFFF;就会做类似的事情。 - chqrlie
1个回答

3
即使在 main 函数结束时内联汇编指令序列也会生成需要执行的代码。在我的环境中,objdump -d foo.o 显示如下:
00000000004004b4 <main>:
  4004b4:   55                      push   %rbp
  4004b5:   48 89 e5                mov    %rsp,%rbp

00000000004004b8 <value>:
  4004b8:   ff                      (bad)  
  4004b9:   ff                      (bad)  
  4004ba:   ff                      (bad)  
  4004bb:   ff                      (bad)  
  4004bc:   b8 01 00 00 00          mov    $0x1,%eax
  4004c1:   5d                      pop    %rbp
  4004c2:   c3                      retq   

这可以通过跳过它来减轻。
asm("jmp 1f"
    "value: .long 0xffffffff"
    "1:");

关键字Nf或Nb创建局部临时标签以向前或向后跳转。

另一种选择是将变量放置到命名段中,该命名段可以在链接器文件中作为.text或.data中的最后一个段进行排序。


jmp 1f 中的 f 是什么意思? - robert
这是用于标签1:的_前向_声明。 - Aki Suihkonen
你如何确保 value 的正确对齐?使用 .long 是否会使其隐式对齐? - chqrlie
@AkiSuihkonen 我不相信这是正确的。GNU汇编器 docs 说:“对于其他系统,包括i386[...],它是位置计数器在前进后必须具有的低位零位的数量。例如,.align 3将使位置计数器前进到8的倍数。” 因此,我认为要正确地对齐一个长整型,你应该使用.align 2。这似乎很奇怪。 - David Wohlferd
@DavidWohlferd:你的[...]剪裁掉了一个重要部分 "对于其他系统,包括 ppc、i386 使用 a.out 格式"。GCC 通常会输出 ELF 格式(即使默认生成的文件名称为 a.out)。由于 Aki 可能正在发出 ELF,所以对齐将是以字节为单位指定的对齐方式。可以使用链接器选项 -Wl,--oformat= 覆盖 GCC 输出其他格式。 - Michael Petch
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接