c语言调用函数堆栈平衡 c语言用堆栈加减乘除运算( 二 )


int func(int a, int* b) {
// float要用到CPU的FPU,指令记不得,要查下
// 为了简单就改为int*
printf("a = %d, b = %d\n", a, *b);
return a;
【c语言调用函数堆栈平衡 c语言用堆栈加减乘除运算】}
编译成机器码后,反编译,如果不加优化,一般都会这样:
(假设函数入口地址为0400000h)
sub_0400000:
push rbp
mov rbp,rsp ; C函数参数度取使用堆栈式
; 参数在内存中这样: |...| a | b | ... |
; 由于是64位 , 故8字节对齐
mov rax,[rbp+8] ; rax = *(rbp+8) // 这里就是 rax = a
push rsi
mov rsi,[rbp+16] ; rsi = *(rbp+16) // rsi = b
; 调用C函数都是这样堆栈式,最后一个参数最先入栈
push [rsi]
push rax
push "a = %d, b = %d\n" ; 这里是便于理解,实际上是push这个字符串常量的指针
call printf ; printf("a = %d, b = %d\n",rax,*rsi)
add rsp,24 ; 平衡堆栈,用了3个参数,要还原3*8=24字节,但根据函数类型的不同去平衡,像调用VB的函数就不需要平衡堆栈……
; 还原数据
mov rsp,rbp
pop rsi
pop rbp
; 一般返回数据都用rax装载
mov rax,[rbp+8] ;rax=a
ret ; return rax
想调用未知参数列表的函数就是把以上过程倒过来 , 看着汇编把C的代码写出来……
破解注册码什么也是这样玩的……
实际上你可以直接用反编译的软件 , 比如IDA , 直接自动分析 , 它反编译的虽然是汇编,但参数列表还是大部分都显示的……
但是 , 当编译器加优化大部分情况就必须自己分析了,因为:
int func(int a, int* b) {
printf("a = %d, b = %d\n", a, *b);
return a;
}
在优化情况下可能为(直接用寄存器传递数据):
sub_040000:
push rdx
mov rdx,rax
push rax
push rbx
push "a = %d, b = %d\n"
call printf
mov rax,rdx
pop rdx
ret
其实像看雪学院有不少这方面的教程……
c语言调用函数堆栈平衡的介绍就聊到这里吧,感谢你花时间阅读本站内容,更多关于c语言用堆栈加减乘除运算、c语言调用函数堆栈平衡的信息别忘了在本站进行查找喔 。

推荐阅读