GNU汇编器:获取标签/变量的地址[INTEL语法]

6

我有这样一段代码:

.bss
woof: .long 0

.text
bleh:
...some op codes here.

现在我想把woof的地址移动到eax中。在英特尔语法中,这里要怎么写代码呢?同样的,如果要将bleh的地址移动到ebx中,应该怎么办呢?

非常感谢您的帮助!

1个回答

9
“bss”部分不能有任何实际的对象。一些汇编器仍然允许您切换到“.bss”部分,但在那里你只能做类似于这样的事情:x: . = . + 4
现在大多数汇编器(特别是gnu for intel)不再使用.bss指令,因此您可以暂时切换到bss并使用以下命令一次性创建bss符号:.comm sym,size,alignment。这就是为什么您可能会收到错误信息“bss directive not recognized”或类似信息。
然后,您可以使用以下任一方法获取地址:
lea woof, %eax

或者

movl $woof, %eax

更新:啊哈,是英特尔语法,而不是英特尔架构。好的:
.intel_syntax noprefix
    lea    esi,fun
    lea    esi,[fun]
    mov     eax,OFFSET FLAT:fun
.att_syntax
    lea     fun, %eax
    mov     $fun, %eax
.data
fun: .long 0x123

所有的“lea”形式都应该生成相同的代码。

谢谢,非常有启发性。不过,我的关注点并不是BSS或数据段。我只需要知道如何使用GNU INTEL语法将标签的地址加载到地址中,而不是AT&T的语法。 我尝试了mov eax,woof和mov eax,dword ptr [woof],但两者都给出了相同的结果。 我想做的事情类似于movl $woof,%eax,但使用GNU Intel语法。 - jian2587
谢谢DigitalRoss!我也在使用lea,但我想知道是否可以使用mov来完成。我猜OFFSET FLAT是关键? - jian2587
没错,有多种寻址模式;MOV指令可以加载立即数,这个立即数也可能是一个地址,或者它可以加载一个地址的内容。通常在Unix上,这是movl $woof,%eaxmovl woof,%eax之间的区别,但在Intel语法中,它会更加啰嗦一些。无论如何,“是的”,lea和mov都可以加载一个地址。 - DigitalRoss
1
顺便说一下,在32位模式下,始终使用mov $foo, regmov reg, OFFSET foo,而不是LEA。LEA比较冗长,大多数CPU上可以运行的执行端口更少,因此对于将32位常量放入寄存器(包括符号的绝对地址)完全没有意义。(RIP相对LEA在64位代码中很有用,但该机器码特性仅存在于64位模式下,并且它在asm源中具有特殊语法。如何将函数或标签的地址加载到寄存器中 - Peter Cordes

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