当前位置:网站首页>C语言中主函数调用另外一个函数,汇编代码理解
C语言中主函数调用另外一个函数,汇编代码理解
2022-06-12 14:06:00 【kk_forward】
栈的理解
由于主函数在执行过程中,需要从主函数跳到被调用的函数,这就涉及到保存当前函数状态,进入被调函数的操作。这个保存状态的操作就需要用到栈。
栈的结构如下:
关于栈的理解有几点要注意的:
- 栈是由高地址向低地址方向增长
- rsp是堆栈寄存器,里面存放的是栈顶指针的地址
- 栈顶指针只有在需要扩大栈大小或者缩小栈大小的时候,才会向低地址移动,否则向入栈和出栈是根据栈顶指针的偏移量来操作的,栈顶指针不需要移动。
示例代码
主函数call_proc.c
#include"proc.h"
long call_proc()
{
long x1 = 1; int x2 = 2;
short x3 = 3; char x4 = 4;
proc(x1, &x1, x2, &x2, x3, &x3, x4, &x4);
return (x1+x2)*(x3-x4);
}
被调函数proc.c
void proc(long a1, long *a1p,
int a2, int *a2p,
short a3, short *a3p,
char a4, char *a4p)
{
*a1p += a1;
*a2p += a2;
*a3p += a3;
*a4p += a4;
}
汇编代码
利用执行gcc -Og -S xxx.c分别生成两者的汇编代码call_proc.s和proc.s如下(只列出关键部分):
call_proc.s
.file "call_proc.c"
.text
.globl call_proc
.type call_proc, @function
call_proc:
.LFB0:
.cfi_startproc
endbr64
pushq %rbx
.cfi_def_cfa_offset 16
.cfi_offset 3, -16
subq $32, %rsp
.cfi_def_cfa_offset 48
movl $40, %ebx
movq %fs:(%rbx), %rax
movq %rax, 24(%rsp)
xorl %eax, %eax
movq $1, 16(%rsp)
movl $2, 12(%rsp)
movw $3, 10(%rsp)
movb $4, 9(%rsp)
leaq 12(%rsp), %rcx
leaq 16(%rsp), %rsi
leaq 9(%rsp), %rax
pushq %rax
.cfi_def_cfa_offset 56
pushq $4
.cfi_def_cfa_offset 64
leaq 26(%rsp), %r9
movl $3, %r8d
movl $2, %edx
movl $1, %edi
call [email protected]
movslq 28(%rsp), %rcx
addq 32(%rsp), %rcx
movswl 26(%rsp), %edx
movsbl 25(%rsp), %eax
subl %eax, %edx
movslq %edx, %rax
imulq %rcx, %rax
addq $16, %rsp
.cfi_def_cfa_offset 48
movq 24(%rsp), %rdi
xorq %fs:(%rbx), %rdi
jne .L4
addq $32, %rsp
.cfi_remember_state
.cfi_def_cfa_offset 16
popq %rbx
.cfi_def_cfa_offset 8
ret
proc.s
.file "proc.c"
.text
.globl proc
.type proc, @function
proc:
.LFB0:
.cfi_startproc
endbr64
movq 16(%rsp), %rax
addq %rdi, (%rsi)
addl %edx, (%rcx)
addw %r8w, (%r9)
movl 8(%rsp), %edx
addb %dl, (%rax)
ret
.cfi_endproc
汇编代码分析
先分析call_proc.s中的汇编代码
更改栈的大小
subq $32, %rsp //将rsp减少32个字节,因为栈的增长方向是大地址往小地址,相当于增大栈的容量
保存局部变量
//将局部变量压栈,rsp前面的数字是相当于栈顶指针的偏移量
movq $1, 16(%rsp)
movl $2, 12(%rsp)
movw $3, 10(%rsp)
movb $4, 9(%rsp)
做完上述操作,栈的示意图如下:
保存被调函数的形参
因为该被调函数有8个形参,但是最多只有6个形参能保存到寄存器中,因此有两个被保存到了栈中,且是形参的最后两个值。
//将形参保存到寄存器中
leaq 12(%rsp), %rcx //load effective adress,用于一个内存地址直接赋给目的操作数
leaq 16(%rsp), %rsi
//将形参保存到栈中,
leaq 9(%rsp), %rax
pushq %rax //将寄存器中的数压栈
pushq $4 // 将立即数压栈
//将形参保存到寄存器中
leaq 26(%rsp), %r9
movl $3, %r8d
movl $2, %edx
movl $1, %edi
参数和形参的对应关系如下图所示:
调用被调函数
call [email protected]
调用被调函数前,会把调用代码的的下一条执行指令压栈,方便从被调函数中返回到主函数时候,还能往下执行。
返回
... //一系列逻辑操作
ret
被调函数汇编代码
逻辑运算
movq 16(%rsp), %rax
// 直接从寄存器中取出运算数
addq %rdi, (%rsi)
addl %edx, (%rcx)
addw %r8w, (%r9)
//从栈中取出运算数
movl 8(%rsp), %edx
addb %dl, (%rax)
返回
ret
总结
- 嵌套的函数调用,需要用栈来保存局部变量、形参、返回时候的指令地址
- C语言的参数是按照从右到左的顺序压到栈中的
参考
边栏推荐
- Tlm/systemc: TLM socket binding problem
- Briefly describe the difference between CGI and fastcgi
- Acwing: topology sequence
- 使用make方法创建slice切片的坑
- 阿里云开发板HaaS510连接物联网平台--HaaS征文
- 动态搜索广告智能查找匹配关键字
- 如何使用android studio制作一个阿里云物联网APP
- SystemC learning materials
- Alibaba cloud development board haas510 submission device attributes
- Dismantle and modify the advertising machine - Amateur decompression
猜你喜欢

Redis核心配置和高级数据类型

Leetcode 2185. 统计包含给定前缀的字符串

After reading the question, you will point to offer 16 Integer power of numeric value

Tlm/systemc: TLM socket binding problem

Dismantle and modify the advertising machine - Amateur decompression

Crack WinRAR to ad pop-up window

Briefly describe the difference between CGI and fastcgi

高考回憶錄

Summary of virtual box usage problems

浅谈中国程序员为什么要跳槽?
随机推荐
Player actual combat 16 xdecode class
What is automatic bidding? What are its advantages?
完美收官|详解 Go 分布式链路追踪实现原理
[semidrive source code analysis] [x9 chip startup process] 25 - Introduction to mailbox inter core communication mechanism (code analysis) rpmsg-ipcc RTOS & QNX
Why do Chinese programmers change jobs?
[wustctf2020] selfie score query -1
Redis core configuration and advanced data types
Player practice 20 audio thread and video thread
初学者入门阿里云haas510开板式DTU(2.0版本)--510-AS
Leetcode 2176. 统计数组中相等且可以被整除的数对
[semidrive source code analysis] [x9 chip startup process] 26 - LK of R5 safetyos_ INIT_ LEVEL_ Target phase code flow analysis (TP drvier, audio server initialization)
Programmer interview golden classic good question / interview question 01.05 Edit once
[video lesson] a full set of tutorials on the design and production of Android studio Internet of things app -- all mastered during the National Day
动态搜索广告智能查找匹配关键字
【mysql进阶】查询优化原理与方案(六)
Display logs in the database through loganalyzer
Bridging and net
【mysql进阶】mysql索引数据结构的演变(四)
Running phase of SystemC
编译安装基于fastcgi模式的多虚拟主机的wordpress和discuz的LAMP架构