【问题标题】:.set label, . Vs. label: GNU AS. 设置标签,.比。标签:GNU AS
【发布时间】:2019-07-04 00:21:45
【问题描述】:

在 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, . 的简写?

【问题讨论】:

  • 与标签不同,您可以多次.set 某事,它会保留其最后一个值。

标签: assembly x86 gnu-assembler


【解决方案1】:

非常有趣的问题。我以前从未见过有人这样做。简而言之,是的,它们有点不同。以下是几个案例:

本地标签

这行得通:

// 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:

如果您想确保不重复使用之前定义的符号,请使用 .eqv.equiv

说到速记:赋值运算符

=== 运算符也可用于设置符号值。见Setting Symbols

// This...
a=.
// ... is equivalent to
.set a, .
// ... or this (since .set and .equ are synonymous)...
.equ a, .

// And this...
a==.
// ... is equivalent to...
.eqv a, .

如需ab使用的示例,请参阅code golf challenge

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-01-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-11-23
    • 1970-01-01
    相关资源
    最近更新 更多