如何解释这个IA32汇编代码

时间:2013-10-13 16:28:25

标签: c assembly x86

作为一项任务,我必须阅读汇编代码并编写其高级C程序。这种情况下的结构是switch语句,因此对于每种情况,汇编代码都转换为C代码中的大小写。以下只是其中一个案例。如果你能帮助我解释这一点,它应该让我更好地理解其他案例。

p1 is in %ebp+8
p2 is in %ebp+12
action is in %ebp+16
result is in %edx

...
.L13:
    movl 8(%ebp), %eax    # get p1
    movl (%eax), %edx     # result = *p1?
    movl 12(%ebp), %ecx   # get p2
    movl (%ecx), %eax     # p1 = *p2
    movl 8(%ebp), %ecx    # p2 = p1
    movl %eax, (%ecx)     # *p1 = *p2?
    jmp .L19              #jump to default
...
.L19
    movl %edx, %eax       # set return value

当然,我添加了评论以试图理解它,除了它让我更加困惑。这意味着交换吗?可能不是;格式会有所不同。第2和第6行真的发生了什么?为什么%edx只是如此早更改一次,如果它是返回值?请回答一些指导原则来解释此代码。

1 个答案:

答案 0 :(得分:4)

以上片段是(IMO已破坏)AT& T语法中的x86_32程序集。

AT& T语法为每个操作数附加一个大小后缀。

movl表示32位操作数。 (l长)b movw表示16位操作数(w表示单词)
movb表示8位操作数(b表示字节)

操作数按顺序颠倒,因此目标位于右侧,源位于左侧 这与几乎所有其他编程语言相反。

寄存器名称以%为前缀,以区别于变量名称。 如果寄存器被括号()包围,则意味着使用寄存器指向的存储器地址,而不是寄存器本身内的值。
这是有道理的,因为EBP被用作指向堆栈帧的指针 Stackframes用于访问函数中的参数和局部变量。

而不是写:mov eax, dword ptr [ebp+8] (英特尔语法)
AT& T语法将其列为:movl 8(%ebp), %eax (gas syntax)

这意味着:将(ebp + 8)指向的内存地址的争议放入eax。

这是翻译:

.L13:   <<-- label used as a jump target. 
    movl 8(%ebp), %eax    <<--  p1, stored at ebp+8 goes into EAX
    movl (%eax), %edx     <<-- p1 is a pointer, EDX = p1->next
    movl 12(%ebp), %ecx   <<-- p2, stored at ebp+12 goes in ECX
    movl (%ecx), %eax     <<-- p2 is (again) a pointer, EAX = p2->next
    movl 8(%ebp), %ecx    <<-- ECX = p1
    movl %eax, (%ecx)     <<-- p2->next = p1->next 
    jmp .L19              <<-- jump to exit 
...
.L19
    movl %edx, %eax       <<-- EAX is always the return value
                          <<-- return p1->data.

在x86的所有调用约定中,函数的返回值都放入EAX寄存器中。 (或EAX:EDX,如果它是INT64)

在散文中:p1和p2是指向数据的指针,在这个数据指针指针中 此代码看起来像操纵链表 p2->next设置为p1->next 除此之外,该片段看起来不完整,因为p2->next中的任何内容都没有开始,因此可能会有更多代码没有显示。

除了令人困惑的AT&amp; T语法之外,它的代码非常简单。

在C代码中,代码如下:

(void *)p2->next = (void *)p1->next;

请注意,代码效率很低,没有合适的编译器(或人工)生成此代码。

以下等价物会更有意义:

mov eax,[ebp+8]
mov ecx,[ebp+12]
mov eax,[eax]
mov [ecx],eax
jmp done

有关AT&amp; T和Intel语法之间差异的更多信息,请访问:http://www.ibm.com/developerworks/linux/library/l-gas-nasm/index.html