一个简单C程序的汇编程序执行分析

1.冯诺依曼体系结构——存储程序式计算机

冯诺依曼体系结构核心是存储程序,将数据和代码都存储在存取器中,都是二进制数据,通过特定模块来区分数据和代码。冯诺依曼体系结构的计算机包括运算器、控制器、存储器、输入单元、输出单元五大件。


image

2.x86汇编

2.1 32位CPU寄存器结构

x86寄存器结构.png

1.开头为e的寄存器一般都为32位寄存器,以R开头的寄存器一般为64位寄存器
2.通常情况下eax作为累加器,ebx作为基址寄存器,ecx作为计数器,edx作为数据寄存器,ebp作为堆栈基指针寄存器(栈底),esi、edi作为变址寄存器,esp作为堆栈顶指针寄存器。

2.2 汇编指令

1.mov:movl l 代表32位

mov.png

register mode :寄存器寻址。
immediate:立即寻址 $+数字:代表的是一个立即数。只有数字:代表的是一个地址
direct:直接寻址。直接访问一个指定的内存地址数据
indirect:间接寻址。将ebx中存储的值作为一个地址,从这个地址取出的值赋给edx
displaced:变址寻址。

2.pushl:入栈
栈是向下增长的,ebp(栈基址指针)指向栈底,esp(堆栈顶指针)指向栈顶。入栈:esp向乡下移动4个字节,然后将eax中的值村放入esp中。
pushl %eax相当于:

subl $4, %esp
movl %eax, (%esp)

3.popl: 出栈
popl %eax相当于:

movl (%esp), %eax
add $4, %esp            

4.call 0x12345:

pushl %eip(*)
movl 0x12345, %eip(*)

eip寄存器,用来存储CPU下一条要执行的指令的地址
5.ret

popl %eip(*)

(*)表示 程序员不能直接使用
6.leave:

movl %ebp, %esp
pop %ebp

3.C程序反汇编分析

代码如下:

int g(int x)
{
    return x + 3;   
}

int f(int x)
{
    return g(x);    
}

int main(void)
{
    return f(8) + 1;    
}

编译成汇编代码:

gcc -S main.c -o main.s -m32 //以32位编译

汇编后的代码(去掉以.开头的部分,这部分是编译器链接用的)

g:
    pushl   %ebp
    movl    %esp, %ebp
    movl    8(%ebp), %eax
    addl    $3, %eax
    popl    %ebp
    ret
f:
    pushl   %ebp
    movl    %esp, %ebp
    subl    $4, %esp
    movl    8(%ebp), %eax
    movl    %eax, (%esp)
    call    g
    leave
    ret
main:
    pushl   %ebp
    movl    %esp, %ebp
    subl    $4, %esp
    movl    $8, (%esp)
    call    f
    addl    $1, %eax
    leave
    ret

eip:当一个指令执行完成之后,自动指向下一个指令
eax:函数返回值默认使用eax寄存器存储返回给上一级函数

接下来,分析一下堆栈调用过程:
首先main():假设栈在内存中的起始地址为0,ebp和esp均指向栈首地址0.

pushl   %ebp
movl    %esp, %ebp
subl    $4, %esp
movl    $8, (%esp)

以上代码为:main函数中开辟新的内存区域,然后将参数 8 入栈、


image

接下来,调用

call    f

call f 相当于;

pushl %eip
movl f, %eip

eip中存的是当前指令的的地址。首先将eip入栈,然后将f中第一个指令的地址赋给eip。此时栈情况如下图所示:


image

此时,此时eip指向f中的pushl %ebp

pushl   %ebp
movl    %esp, %ebp
subl    $4, %esp
movl    8(%ebp), %eax
movl    %eax, (%esp)

为f函数开辟栈空间,然后将参数8赋值给eax,最后将eax入栈,具体操作过程如下:


image

接下来,运行

call    g

调用g函数,此时栈情况如下:


image

接下来,执行

 pushl   %ebp
 movl    %esp, %ebp
 movl    8(%ebp), %eax
 addl    $3, %eax
 popl    %ebp //将ebp指向的值赋给ebp
 ret//相当于:popl eip

栈调用过程如下:


image

此时,eip指向否f函数中的 leave

leave
ret

此时eip指向 MIan函数中的 addl $1, %eax


image

接下来执行 main函数

 addl    $1, %eax//11 + 1

此时eax = 12
接下来执行

leave
ret
image

4.总结

堆栈:高级语言的函数调用。是高级语言的基础
堆栈是C程序运行时必须的一个记录调用路径和参数的空间。
堆栈作用:

  • 函数调用框架
  • 传递参数
  • 保存返回地址
  • 提供局部变量空间
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,830评论 5 468
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,992评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,875评论 0 331
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,837评论 1 271
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,734评论 5 360
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,091评论 1 277
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,550评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,217评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,368评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,298评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,350评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,027评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,623评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,706评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,940评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,349评论 2 346
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,936评论 2 341

推荐阅读更多精彩内容