Assembly 汇编语言中printf函数的额外步骤

Assembly 汇编语言中printf函数的额外步骤,assembly,stack,Assembly,Stack,原始代码: void main() { int x = 1; printf("%d\n", x); } 相应的装配代码为: |0x80483f5 <main+17> mov $0x80484e0,%eax │0x80483fa <main+22> mov 0x1c(%esp),%edx │0x80483fe <main+26> mov %edx,0x4(%esp) │0x804

原始代码:

void main()
{
    int x = 1;
    printf("%d\n", x);
}
相应的装配代码为:

   |0x80483f5 <main+17>     mov    $0x80484e0,%eax
   │0x80483fa <main+22>     mov    0x1c(%esp),%edx
   │0x80483fe <main+26>     mov    %edx,0x4(%esp)
   │0x8048402 <main+30>     mov    %eax,(%esp)
   │0x8048405 <main+33>     call   0x8048300 <printf@plt>

It first moves the string "%d\n" in %eax          ---->Extra Step
Then it moves the value of 0x1c(%esp) in %edx     ---->Extra Step
| 0x80483f5 mov$0x80484e0,%eax
│0x80483fa mov 0x1c(%esp),%edx
│0x80483fe mov%edx,0x4(%esp)
│0x8048402 mov%eax,(%esp)
│0x8048405呼叫0x8048300
它首先在%eax-->额外步骤中移动字符串“%d\n”
然后将0x1c(%esp)的值移动到%edx-->额外步骤中
然后将这两个值放在堆栈顶部,用于标准过程调用,即调用printf()


我的问题是,为什么要增加两个步骤?为什么它不能简单地从内存中获取这些值并直接将其保存在堆栈中,而不是使用两个寄存器?

x86体系结构没有
mov
指令(除了
movs
,但这与此无关)这可以从内存复制到内存,这就是为什么代码在将参数复制到堆栈时使用寄存器临时存储参数的原因


请注意,
push
可以与内存操作数一起使用,但可能堆栈指针已经过调整,以便为参数分配空间。

如果在编译时启用了所有优化(假设尚未启用),程序集会有很大不同吗?