C 代码表示为汇编代码 - 如何解释?

标签 c assembly x86 disassembly

我得到了这个简短的 C 代码。

#include <stdint.h>
uint64_t multiply(uint32_t x, uint32_t y) {

uint64_t res;
res = x*y;
return res;
}

int main() {

uint32_t a = 3, b = 5, z;
z = multiply(a,b);
return 0;
}

上面给定的 C 代码还有一个汇编代码。 我不明白该汇编代码的全部内容。我对每一行都进行了评论,您可以在每一行的评论中找到我的问题。

汇编代码是:

.text
multiply:
     pushl  %ebp  // stores the stack frame of the calling function on the stack
     movl   %esp, %ebp // takes the current stack pointer and uses it as the frame for the called function
     subl   $16, %esp // it leaves room on the stack, but why 16Bytes. sizeof(res) = 8Bytes
     movl   8(%ebp), %eax // I don't know quite what "8(%ebp) mean? It has to do something with res, because
     imull  12(%ebp), %eax // here is the multiplication done. And again "12(%ebp).
     movl   %eax, -8(%ebp) // Now, we got a negative number in front of. How to interpret this?
     movl   $0, -4(%ebp) // here as well
     movl   -8(%ebp), %eax // and here again.
     movl   -4(%ebp), %edx // also here
     leave
     ret
main:
     pushl  %ebp // stores the stack frame of the calling function on the stack
     movl   %esp, %ebp // // takes the current stack pointer and uses it as the frame for the called function
     andl   $-8, %esp // what happens here and why?
     subl   $24, %esp // here, it leaves room for local variables, but why 24 bytes? a, b, c: the size of each of them is 4 Bytes. So 3*4 = 12
     movl   $3, 20(%esp) // 3 gets pushed on the stack
     movl   $5, 16(%esp) // 5 also get pushed on the stack
     movl   16(%esp), %eax // what does 16(%esp) mean and what happened with z?
     movl   %eax, 4(%esp) // we got the here as well
     movl   20(%esp), %eax // and also here
     movl   %eax, (%esp) // what does happen in this line?
     call   multiply  // thats clear, the function multiply gets called
     movl   %eax, 12(%esp) // it looks like the same as two lines before, except it contains the number 12
     movl   $0, %eax // I suppose, this line is because of "return 0;"
     leave
     ret

最佳答案

相对于 %ebp 的负引用适用于堆栈上的局部变量。

 movl   8(%ebp), %eax // I don't know quite what "8(%ebp) mean? It has to do something with res, because`

%eax = x

 imull  12(%ebp), %eax // here is the multiplication done. And again "12(%ebp).

%eax = %eax * y

 movl   %eax, -8(%ebp) // Now, we got a negative number in front of. How to interpret this?

(u_int32_t)res = %eax//设置 res 的低 32 位

 movl   $0, -4(%ebp) // here as well

清除res的高32位以将32位乘法结果扩展为uint64_t

 movl   -8(%ebp), %eax // and here again.
 movl   -4(%ebp), %edx // also here

返回ret;//64 位结果作为一对 32 位寄存器返回 %edx:%eax

主要参见x86 calling convention这可能有助于理解发生的事情。

 andl   $-8, %esp // what happens here and why?

堆栈边界按 8 对齐。我相信这是 ABI 要求

 subl   $24, %esp // here, it leaves room for local variables, but why 24 bytes? a, b, c: the size of each of them is 4 Bytes. So 3*4 = 12

8 的倍数(可能是由于对齐要求)

 movl   $3, 20(%esp) // 3 gets pushed on the stack

a = 3

 movl   $5, 16(%esp) // 5 also get pushed on the stack

b = 5

 movl   16(%esp), %eax // what does 16(%esp) mean and what happened with z?

%eax = b

z 位于 12(%esp),尚未使用。

 movl   %eax, 4(%esp) // we got the here as well

将 b 放入堆栈(multiply() 的第二个参数)

 movl   20(%esp), %eax // and also here

%eax=a

 movl   %eax, (%esp) // what does happen in this line?

将 a 放入堆栈(multiply() 的第一个参数)

 call   multiply  // thats clear, the function multiply gets called

乘以 %edx:%eax 形式返回 64 位结果

 movl   %eax, 12(%esp) // it looks like the same as two lines before, except it contains the number 12

z = (uint32_t) 乘法()

 movl   $0, %eax // I suppose, this line is because of "return 0;"

是的。返回0;

关于C 代码表示为汇编代码 - 如何解释?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19984869/

相关文章:

c - 如何在for循环中输入if语句?

assembly - iPad 组装开发

c - 解释这个汇编代码

x86 - CPU中的新指令集

x86:超越函数的延迟和吞吐量

从不同大小的整数转换为指针 [-Wint-to-pointer-cast]

c++ - 开发环境沙盒

c - 在C中使用 token 的函数中的编译错误

c++ - 如何在汇编函数中将元素数组作为参数传递时转发 ARM 寄存器的地址指针

linux - 指令内存地址是否改变?