实验一 反汇编一个简单的C程序
1、使用vim test1.c命令打开vim编辑器,以test1.c为名创建文件
2、编写一个简单的程序后,使用:wq保存并退出编译。
3、执行反汇编命令gcc –S –o mian.s mian.c
得到test1.s文件,删除所有.开头的行得到纯汇编代码即:
-
g:
-
pushq %rbp
-
movq %rsp, %rbp
-
movl %edi, -4(%rbp)
-
movl -4(%rbp), %eax
-
addl $20, %eax
-
popq %rbp
-
ret
-
f:
-
pushq %rbp
-
movq %rsp, %rbp
-
subq $8, %rsp
-
movl %edi, -4(%rbp)
-
movl -4(%rbp), %eax
-
movl %eax, %edi
-
call g
-
leave
-
ret
-
main:
-
pushq %rbp
-
movq %rsp, %rbp
-
movl $50, %edi
-
call f
-
subl $50, %eax
-
popq %rbp
-
ret
4、通过和ChatGPT深入了解代码及相关知识
问题:请详细解释上述汇编代码。
答:
这段汇编代码看起来是一个简单的x86-64汇编语言程序,它定义了三个函数:g
、f
和 main
。以下是对每个函数的详细解释:
函数 g
-
g:
-
pushq %rbp ; 保存调用者的栈帧
-
movq %rsp, %rbp ; 设置当前栈帧
-
movl %edi, -4(%rbp) ; 将第一个参数 %edi 存储在栈帧中的偏移 -4(%rbp) 处
-
movl -4(%rbp), %eax ; 从栈帧中加载值到寄存器 %eax
-
addl $20, %eax ; 将 20 添加到 %eax
-
popq %rbp ; 恢复调用者的栈帧
-
ret ; 返回,将结果存储在 %eax 中
函数 g
接受一个整数参数,并将参数值加上 20,然后将结果存储在 %eax
寄存器中,并通过 ret
指令返回。
函数 f
-
f:
-
pushq %rbp ; 保存调用者的栈帧
-
movq %rsp, %rbp ; 设置当前栈帧
-
subq $8, %rsp ; 在栈上分配 8 个字节的空间
-
movl %edi, -4(%rbp) ; 将第一个参数 %edi 存储在栈帧中的偏移 -4(%rbp) 处
-
movl -4(%rbp), %eax ; 从栈帧中加载值到寄存器 %eax
-
movl %eax, %edi ; 将 %eax 中的值赋给 %edi 寄存器
-
call g ; 调用函数 g,g 的返回值存储在 %eax 中
-
leave ; 恢复调用者的栈帧并释放栈空间
-
ret ; 返回,将结果存储在 %eax 中
函数 f
接受一个整数参数,将该参数传递给函数 g
,并将 g
的返回值作为自己的返回值。在执行之前,它在栈上分配了8个字节的空间。
函数 main
-
main:
-
pushq %rbp ; 保存调用者的栈帧
-
movq %rsp, %rbp ; 设置当前栈帧
-
movl $50, %edi ; 将值 50 存储在 %edi 寄存器中
-
call f ; 调用函数 f,f 的返回值存储在 %eax 中
-
subl $50, %eax ; 将 %eax 中的返回值减去 50
-
popq %rbp ; 恢复调用者的栈帧
-
ret ; 返回,将结果存储在 %eax 中
函数 main
首先将整数值 50 存储在 %edi
寄存器中,然后调用函数 f
,将 f
的返回值存储在 %eax
中。接下来,它从 %eax
中减去 50,最后返回结果。
整个程序的目的似乎是计算 g(f(50)) - 50
的值,并将结果存储在 %eax
中。
然后是与ChatGPT的相关对话: