Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Assembly 在gnu汇编程序中为x86_64处理器系列设置常量的正确方法是什么_Assembly_X86 64_Constants_Gnu Assembler_Nm - Fatal编程技术网

Assembly 在gnu汇编程序中为x86_64处理器系列设置常量的正确方法是什么

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

我正在自学x86#U 64汇编,我的参考文本是英特尔语法,我对在gnu汇编程序中使用AT&T语法很感兴趣,并且已经找出了其中的大部分区别,但我无法找出设置类似于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/.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预处理器。