当前位置:网站首页>C語言中主函數調用另外一個函數,匯編代碼理解
C語言中主函數調用另外一個函數,匯編代碼理解
2022-06-12 14:15: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語言的參數是按照從右到左的順序壓到棧中的
參考
边栏推荐
- Player practice 18 xresample
- Crack WinRAR to ad pop-up window
- Is MySQL query limit 1000,10 as fast as limit 10? How to crack deep paging
- Lua tvalue structure
- How to realize the bidding strategy that pays more attention to transformation in the company's operation Google sem
- Lua callinfo structure, stkid structure resolution
- Details of bypassing safeseh mechanism by using modules that do not enable safeseh
- Knowledge of wireless card driver
- Alibaba cloud development board haas510 parses serial port JSON data and sends attributes
- Leetcode 2185. 统计包含给定前缀的字符串
猜你喜欢

公司运营中更注重转化的出价策略,如何实现? —Google sem

Alibaba Cloud Development Board haas510 submission Device Properties
![[early knowledge of activities] list of recent activities of livevideostack](/img/d8/a367c26b51d9dbaf53bf4fe2a13917.png)
[early knowledge of activities] list of recent activities of livevideostack

Talk about the top 10 classic MySQL errors

Go language functions as parameters of functions

Player actual combat 21 audio and video synchronization
![[advanced MySQL] evolution of MySQL index data structure (IV)](/img/eb/e32387b172eb4c3a4152dbc3b0cb8f.png)
[advanced MySQL] evolution of MySQL index data structure (IV)

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

Communication flow analysis

Dynamic search advertising intelligent search for matching keywords
随机推荐
Summary of virtual box usage problems
Printing colored messages on the console with printf
Alibaba Cloud Development Board haas510 submission Device Properties
【活动早知道】LiveVideoStack近期活动一览
阿里云开发板HaaS510报送设备属性
Chapter IV expression
Player practice 19 xaudio turn on audio
Player actual combat 22 to solve the problems of flower screen and Caton
Implementation of Ackermann function with simulated recursion
The original Xiaoyuan personal blog project that has been around for a month is open source (the blog has basic functions, including background management)
Player practice 20 audio thread and video thread
TestEngine with ID ‘junit-vintage‘ failed to discover tests
280 weeks /2171 Take out the least number of magic beans
What is the default gateway
Player practice 18 xresample
Is MySQL query limit 1000,10 as fast as limit 10? How to crack deep paging
Player actual combat 13 create qtopengl project to promote window control and reload qoopenglwedge
Tree reconstruction (pre order + middle order or post order + middle order)
[wustctf2020] selfie score query -1
Lua common built-in functions