Loading

C & x86msvc_asm第一天

做浙大PTA的7-105 寻找250时候,对scanf的的机制不太熟悉,于是想到联系之前学过的汇编来理解。
image.png
这里可以看出,scanf接受一个指针和一个变量地址。注意这里的OFFSET操作符,相当于C++中的&。
%d也就是缓冲区里的内容,放到_tmp$[ebp]里面。但是这里汇编看不到_scanf的细节,这里先不讨论。
为了学习逆向,我选择先巩固逆向所需要的汇编知识,利用pta的编程题,多对比学习c和assembly language。

main函数的汇编

image.png

在 x86 汇编语言中,EBP 寄存器通常在函数的开头被初始化为栈帧的基地址。然后,它被用作基址指针和帧指针,以访问函数的局部数据和返回地址。

main函数实质上也是一个函数,每个函数调用之前,需要保存调用之前的状态,即使main函数也不例外。
为了做到这件事情,需要有一个地方保存函数调用前堆栈的状态,ebp就是这个地方。
函数头为新函数的调用做好准备,很容易想到,它需要完成两件事情。分别是辞旧、迎新。

  1. ebp入栈,这是为了保存原函数的状态地址。也就是辞旧
  2. ebp指向当前栈顶esp,这是初始化调用函数空间,将其指向栈空间的顶部,为使用“专属”的栈空间做好准备。也就是迎新

函数尾为新函数的调用做好收尾工作,先看其中最重要的一件事:

  1. 恢复函数头存储的ebp的地址,即回到原函数的地址空间。

另外两件事情:

  1. eax寄存器清零,格式化通用寄存器。
  2. ret 0,该指令的作用是返回到调用函数,并以 0 作为返回值。实际上这里是__stdcall调用方式,参数使用栈传递,被调用者即main函数负责释放参数空间。

scanf操作符的汇编

image.png
相当于
image.png
lea指令相当于对后者取地址,放到前者里面。类比于C++中的取地址符&
这里是__stdcall的函数调用约定,使用栈空间进行传递参数,最后esp+8出栈。

posted @ 2024-04-18 20:24  _rainyday  阅读(47)  评论(0)    收藏  举报