Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/assembly/6.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
C 是否确定存储了哪些寄存器参数和变量?_C_Assembly_X86 64_Att - Fatal编程技术网

C 是否确定存储了哪些寄存器参数和变量?

C 是否确定存储了哪些寄存器参数和变量?,c,assembly,x86-64,att,C,Assembly,X86 64,Att,我仍然不确定汇编程序是如何使用寄存器的 假设我有一个程序: int main(int rdi, int rsi, int rdx) { rdx = rdi; return 0; } 这在汇编中是否可以翻译为: movq %rdx, %rdi ret rax; mov %rdi, %rdx # move %rdi into %rdx xor %eax, %eax # zero return value ret # return 我是AT&T的新手,很难预测某个寄存器何

我仍然不确定汇编程序是如何使用寄存器的

假设我有一个程序:

int main(int rdi, int rsi, int rdx) {

    rdx = rdi;

    return 0;
}
这在汇编中是否可以翻译为:

movq %rdx, %rdi 

ret rax;
mov %rdi, %rdx # move %rdi into %rdx
xor %eax, %eax # zero return value
ret # return
我是AT&T的新手,很难预测某个寄存器何时会被使用。 从计算机系统看这张图表——程序员的视角,第三版,R.E.Bryant和D.R.O'Hallaron:


不,它将被翻译成:

movq %rdx, %rdi 

ret rax;
mov %rdi, %rdx # move %rdi into %rdx
xor %eax, %eax # zero return value
ret # return
当然,编译器很可能会删除
rdx=rdi
(因此
mov%rdi,%rdx
),因为不再使用
rdx

幸亏在我之前发现了这一点

是否确定存储了哪些寄存器参数和变量

仅在函数的入口和出口处

无法保证在函数中使用哪些寄存器,即使对于作为函数参数的变量也是如此。编译器可以(通常也会)在寄存器之间移动变量,以优化寄存器/堆栈的使用,特别是在x86等寄存器匮乏的体系结构上


在这种情况下,像
rdx=rdi
这样的简单赋值操作可能根本不会编译成任何汇编代码,因为编译器将简单地识别两个值现在都可以在寄存器
%rdi
中找到。即使对于更复杂的操作,如
rdx=rdi+1
,编译器也可以自由地将值存储在任何寄存器中,而不是专门存储在
%rdx
中。(它甚至可能将值存储回
%rdi
,例如
inc%rdi
,如果它意识到原始值以后从未使用过。)

您忘记了指令,at&t使用src、dst顺序,因此它是
mov%rdi,%rdx
。当然,任何优化编译器都会删除它,因为没有使用
rdx
。另外,
ret-rax
也没有意义,尤其是因为您的代码有一个
返回0
。例如,
xor%eax,%eax;将
归零
rax
并返回。在可以查看GCC、clang、ICC或MSVC asm输出的地方自己尝试一下。(也适用于一些非x86 ISA)使用带有三个整数参数的函数名
main()
,这不是一个明显的名称选择-参数的含义是由实现定义的,很可能实际上是未定义的行为。GCC可能会抱怨
main()
函数上的签名不正确。忽略函数名的问题,代码不会处理影响计算状态的参数,优化器很可能会删除赋值。也没有任何东西将名为
rdi
rsi
rdx
的变量与任何具有类似名称的寄存器相关联。当然,除了sysv-abi调用约定之外,它为这些参数指定了这些寄存器。对于我来说,清除了很多,谢谢Jonathani如果你从中抄袭了这篇文章,那么给予他们信任是一种常见的礼貌。如果你把这篇文章做成一篇社区维基文章,也会有所帮助。@MartijnPieters不完全是这样,但我已经添加了一个链接。