首页 > 解决方案 > 在 x86_64 处理器系列的 gnu 汇编程序中设置常量的正确方法是什么

问题描述

我正在自学 x86_64 汇编,我的参考文本是 intel 语法,我有兴趣将 AT&T 语法与 gnu 汇编器一起使用,并且已经找出了大部分差异,但我无法弄清楚设置常量的正确方法类似于C 预处理器的#define 关键字。

例如,让我们以这个简单的 helloworld 示例为例:

.globl _start
_start:
        movq $1, %rax
        movq $1, %rdi
        movq $MESG, %rsi
        movq $13, %rdx
        syscall

        movq $60, %rax
        movq $0, %rdi
        syscall

组装完成后nm,可执行文件的输出为:

0000000000000000 d MESG
0000000000000000 T _start

到目前为止,两个符号都很好,但是接下来是什么。

.globl _start
_start:
        movq SYS_write, %rax
        movq FILENO_STDOUT, %rdi
        movq $MESG, %rsi
        movq $13, %rdx
        syscall

        movq SYS_exit, %rax
        movq $0, %rdi
        syscall

.data
MESG:          .ascii "Hello World\n"
SYS_write:     .quad  1
SYS_exit:      .quad  60
FILENO_STDOUT: .quad 1

此可执行文件的nm输出显示数据部分中的新符号

000000000000001c d FILENO_STDOUT
0000000000000000 d MESG
0000000000000000 T _start
0000000000000014 d SYS_exit
000000000000000c d SYS_write

然而,这不是常量将具有的只读数据,但它是一个开始。

我的下一个想法是将标签粘贴到 .rodata 部分

.globl _start
_start:
        movq SYS_write, %rax
        movq FILENO_STDOUT, %rdi
        movq $MESG, %rsi
        movq $13, %rdx
        syscall

        movq SYS_exit, %rax
        movq $0, %rdi
        syscall

.data

.section .rodata
MESG:          .ascii "Hello World\n"
SYS_write:     .quad  1
SYS_exit:      .quad  60
FILENO_STDOUT: .quad 1

结果是这样的nm

000000000000001c r FILENO_STDOUT
0000000000000000 r MESG
0000000000000000 T _start
0000000000000014 r SYS_exit
000000000000000c r SYS_write

这似乎是我想要的但是我在气体手册中注意到有一个汇编指令 .set / .equ 似乎做同样的事情

.globl _start
_start:
        movq SYS_write, %rax
        movq $FILENO_STDOUT, %rdi
        movq $MESG, %rsi
        movq $13, %rdx
        syscall

        movq SYS_exit, %rax
        movq $0, %rdi
        syscall

.data
MESG:        .ascii "Hello World\n"
SYS_write:   .quad  1
SYS_exit:    .quad  60
#FILENO_STDOUT: .quad 1
.set    FILENO_STDOUT, 1

然而,nm下面的输出显示该符号是小写的“a”,我假设它只是 nm 手册中描述的用于描述绝对符号的“A”的另一种形式。我还注意到,如果我没有为用 set 指令定义的标签放置立即信号,程序会出现段错误。

0000000000000001 a FILENO_STDOUT
0000000000000000 d MESG
0000000000000000 T _start
0000000000000014 d SYS_exit
000000000000000c d SYS_write

如果以上任何一项都是在 gnu 汇编程序中定义常量的正确方法,那么所有这些都是。

标签: assemblyx86-64constantsgnu-assemblernm

解决方案


推荐阅读