简体   繁体   English

宏在 GAS 中替换一个常数

[英]Macro substituting a constant number in GAS

What't wrong with that macro on X86 GNU Assembly? X86 GNU 程序集上的那个宏有什么问题? It says the symbol S is undefined during linking.它表示符号 S 在链接期间未定义。

.macro S size=40
\size
.endm

I'm using it like我像这样使用它

mov %eax, S

Macros are used to create templates for code you frequently use, not to input a constant number.宏用于为您经常使用的代码创建模板,而不是输入常数。 As such, I do not believe the assembler does macro expansion within an expression.因此,我不相信汇编程序会在表达式中进行宏扩展。 Since you simply want a number, you could use .set to define a constant.由于您只需要一个数字,您可以使用.set来定义一个常量。

.set S, 40
mov %eax, S

Also, in case you usually use intel syntax, make sure you realize what this code is doing: It currently stores the value of eax in memory at the address 0x28.此外,如果您通常使用 intel 语法,请确保您了解此代码在做什么:它当前将 eax 的值存储在 memory 的地址 0x28 处。 If you want to put the number 40 in eax, you need to reverse the operands and use a dollar sign in front of S.如果要将数字 40 放入 eax 中,则需要将操作数反转并在 S 前面使用美元符号。

mov $S, %eax

You can also directly assign symbols with the equals sign = :您也可以直接使用等号=分配符号:

S = 40

which the GNU as manual says is equivalent to using .set https://sourceware.org/binutils/docs-2.19/as/Setting-Symbols.html#Setting-Symbols GNU 手册中所说的相当于使用.set https://sourceware.org/binutils/docs-2.19/as/Setting-Symbols.html#Setting-Symbols

A symbol can be given an arbitrary value by writing a symbol, followed by an equals sign =', followed by an expression (see Expressions). This is equivalent to using the.set directive. See.set. In the same way, using a double equals sign可以通过写一个符号,后跟一个等号=', followed by an expression (see Expressions). This is equivalent to using the.set directive. See.set. In the same way, using a double equals sign =', followed by an expression (see Expressions). This is equivalent to using the.set directive. See.set. In the same way, using a double equals sign =', followed by an expression (see Expressions). This is equivalent to using the.set directive. See.set. In the same way, using a double equals sign ='`=' here represents an equivalent of the.eqv directive. =', followed by an expression (see Expressions). This is equivalent to using the.set directive. See.set. In the same way, using a double equals sign ='`=' 表示等效于 .eqv 指令。 See.eqv.见.eqv。

.equ is yet another synonym... .equ是另一个同义词...

 .equ S, 40

One typical use case of such constants, is to calculate the length of static strings, eg the Linux x86_64 hello world can be written as:这种常量的一个典型用例是计算 static 字符串的长度,例如 Linux x86_64 hello world 可以写成:

hello_world.S hello_world.S

    .data
hello_world:
    .ascii "hello world\n"
    hello_world_len = . - hello_world
.text
.global _start
_start:
    /* write */
    mov $1, %rax
    mov $1, %rdi
    mov $hello_world, %rsi
    mov $hello_world_len, %rdx
    syscall

    /* exit */
    mov $60, %rax
    mov $0, %rdi
    syscall

which you can compile and run wth:您可以编译和运行它:

as -o hello_world.o hello_world.S
ld -o hello_world.out hello_world.o
./hello_world.out

GitHub upstream . GitHub 上游

%rdx will then contain the length of the string to be written.然后%rdx将包含要写入的字符串的长度。

The $ is required just like for any regular address label, otherwise you would be trying to access that memory address instead of moving an immediate.就像任何常规地址 label 一样, $是必需的,否则您将尝试访问该 memory 地址而不是移动立即数。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM