Assembly 在gnu汇编程序中为x86_64处理器系列设置常量的正确方法是什么
我正在自学x86#U 64汇编,我的参考文本是英特尔语法,我对在gnu汇编程序中使用AT&T语法很感兴趣,并且已经找出了其中的大部分区别,但我无法找出设置类似于C预处理器的#define关键字的常数的正确方法 例如,让我们以这个简单的helloworld为例:Assembly 在gnu汇编程序中为x86_64处理器系列设置常量的正确方法是什么,assembly,x86-64,constants,gnu-assembler,nm,Assembly,X86 64,Constants,Gnu Assembler,Nm,我正在自学x86#U 64汇编,我的参考文本是英特尔语法,我对在gnu汇编程序中使用AT&T语法很感兴趣,并且已经找出了其中的大部分区别,但我无法找出设置类似于C预处理器的#define关键字的常数的正确方法 例如,让我们以这个简单的helloworld为例: .globl _start _start: movq $1, %rax movq $1, %rdi movq $MESG, %rsi movq $13, %rdx
.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/.eq,它似乎也有同样的作用
.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指令定义的标签放置立即sigal,那么程序segal将出现故障
0000000000000001 a FILENO_STDOUT
0000000000000000 d MESG
0000000000000000 T _start
0000000000000014 d SYS_exit
000000000000000c d SYS_write
所有这些,如果以上任何一项是在gnu汇编程序中定义常量的正确方法。请参阅,是的,您将需要立即使用
$
。.eq
是定义汇编时间常量的常用方法;在其他汇编器中,EQU常量与标签定义的符号甚至比GAS中的符号更为不同。顺便说一句,#包含-使用RIP relative!如果我理解正确的话,那么.eq和.set是汇编时间常数,就像C预处理器#define(基本上是一个立即值的助记符标签),而.byte/.long/.int/.quad/等是分配内存并给它一个值的指令?也谢谢你给我的提示,我没有想到仅仅使用c预处理器。