。set标签,。 VS.标签:GNU AS

问题描述 投票:3回答:1

在GNU汇编器中,当前地址由.表示

这样可以设置一个常数/符号,并像使用标签一样使用它,例如:

.set offset, .
        .long 0x10

.globl _start
_start:
        # %eax should be 0x10
        movl offset, %eax

        # %ebx should be address of offset
        movl $offset, %ebx

        # Value at the address of offset should contain 0x20
        movl $0x20, offset

以上代码的行为与offset是标签而不是符号的行为完全相同。

在任何情况下上述说法都不成立,或者label:确实只是.set label, .的简写吗?

assembly x86 gas
1个回答
0
投票

非常有趣的问题。我从未见过有人这样做。简而言之,是的,它们有些不同。这是几种情况:

本地标签

此作品:

// Local label:
    movq $2, %rax
1:
    decq %rax
    // Branch to preceding local label 1
    jg 1b

但这不是:

// Test the same thing with set:
    movq $2, %rax
.set 1, .
    decq %rax
    // Branch to preceding local label 1
    jg 1b

gcc发出:Error: expected symbol name,因为符号名称不能以数字开头。有关符号名称的更多信息,请参见binutils docs

多个定义

当您使用相同的符号名称拥有两个或多个定义时,标签的行为将有所不同。文档说第一个标签会覆盖所有其他标签,但是实际上,即使使用.set指令,您的编译器甚至都不允许您这样做。另一方面,.set允许您多次分配相同的符号,但是当使用具有相同名称的标签时,此后该符号的值将无法再更改。标签似乎使符号成为“只读”。

多次使用.set时,它始终是最新值,或者,如果尚未设置,则是下一个可用值。

假设我们将以下行插入某处:

remote: jmp retval
jmp remote

//// If inserted here, the program returns -1

// Return -1
.set retval, .
    movq $-1, %rax
    jmp exit

//// If inserted here, the program returns -1

// Return 1 (also works as a label since we don't try to set it again after this)
.set retval, .
    movq $1, %rax
    jmp exit

//// If inserted here, the program returns 1

exit:
© www.soinside.com 2019 - 2024. All rights reserved.