无法理解代码生成的汇编指令

时间:2015-04-08 22:41:32

标签: assembly

我正在学习“计算机系统:程序员视角”一书。我在理解问题3.5时遇到了一些麻烦:

  

您将获得以下信息。具有原型的函数

void decode1(int *xp, int *yp, int *zp);
  

被编译成汇编代码。代码正文如下:

     

xp at%ebp + 8,yp at%ebp + 12,zp at%ebp + 16

1 movl 8(%ebp), %edi

2 movl 12(%ebp), %edx

3 movl 16(%ebp), %ecx

4 movl (%edx), %ebx

5 movl (%ecx), %esi

6 movl (%edi), %eax

7 movl %eax, (%edx)

8 movl %ebx, (%ecx)

9 movl %esi, (%edi)
  

参数xp,yp和zp存储在具有偏移的存储器位置   8,12和16分别相对于寄存器%ebp中的地址。   为decode1编写C代码,其效果等同于   上面的汇编代码。

我提出了以下c函数:

void decode1(int *xp, int *yp, int *zp) {
    int *a = yp;
    int *b = zp;
    int *c = xp;

    yp = c;
    zp = a;
    xp = b;
}

编译到程序集(flags:-w32 -O0 -S)我得到以下汇编代码:

decode1(int*, int*, int*):
pushl   %ebp
movl    %esp, %ebp
subl    $16, %esp
movl    12(%ebp), %eax
movl    %eax, -12(%ebp) // ??
movl    16(%ebp), %eax   
movl    %eax, -8(%ebp)  // ??
movl    8(%ebp), %eax
movl    %eax, -4(%ebp)  // ??
movl    -4(%ebp), %eax
movl    %eax, 12(%ebp)
movl    -12(%ebp), %eax
movl    %eax, 16(%ebp)
movl    -8(%ebp), %eax
movl    %eax, 8(%ebp)
nop
leave
ret

我有两个问题:

我的C代码是否正确?如果是,为什么汇编代码的差异?我不明白为什么代码似乎将变量存回内存然后加载回来?为什么它只使用%eax?我有6个变量,所以它应该能够在6个寄存器中加载它们,没有?


编辑:生成的代码使用-O2而不是-O0

pushl   %ebp
movl    %esp, %ebp
subl    $24, %esp
movl    16(%ebp), %eax
movl    12(%ebp), %ecx
movl    8(%ebp), %edx
movl    %edx, -4(%ebp)
movl    %ecx, -8(%ebp)
movl    %eax, -12(%ebp)
movl    -8(%ebp), %eax
movl    %eax, -16(%ebp)
movl    -12(%ebp), %eax
movl    %eax, -20(%ebp)
movl    -4(%ebp), %eax
movl    %eax, -24(%ebp)
movl    -24(%ebp), %eax
movl    %eax, -8(%ebp)
movl    -16(%ebp), %eax
movl    %eax, -12(%ebp)
movl    -20(%ebp), %eax
movl    %eax, -4(%ebp)
addl    $24, %esp
popl    %ebp
retl

EDIT2:正确答案实际上是:

    void decode1(int *xp, int *yp, int *zp) {
    int a = *yp;
    int b = *zp;
    int c = *xp;

    *yp = c;
    *zp = a;
    *xp = b;
}

0 个答案:

没有答案