设为首页 加入收藏

TOP

C指针原理(87)-helloworld的C程序汇编剖析(3)
2014-11-23 18:02:47 来源: 作者: 【 】 浏览:17
Tags:指针 原理 -helloworld 程序 汇编 剖析

“.LC0”标记的内存位于应用程序的静态分配区域,这个区域在程序运行后即被分配,即“hello,world”作为一个C语言字符串常量被安排在静态分配区域。

还有一个非常重要内存分配区域就是堆栈,,堆栈是特殊的内存区域,用于程序中函数传递参数、数据的临时存取,通常是应用程序内存范围的结尾位置的内存区域,为了方便堆栈数据的存取,有一个堆栈指针(栈顶指针)指向堆栈中的下个内存位置,这意味着如何仅依靠栈顶指针不采用任意偏移地址机制(偏移地址可以以基地址为中心进行调整,比如说访问某个变量,该变量的基地址为0x400,偏移地址为0x16,则该变量的最终地址为0x416),则只能按照先进后出的顺序来访问堆栈内部存储的变量。

在汇编语言中将数据放入堆栈中,使用pushl助记符,而将数据从堆栈中弹出,使用popl助记符,每次对堆栈数据的放入与弹出都会导致栈顶指针的变化,因为栈顶指针永远指向堆栈中下一个可用的地址。下面这段汇编完成了将10压入堆栈,然后将10弹出到ebx寄存器中的过程。

pushl $10

popl %ebx

麦好的AI乐园博客所有内容是原创,如果转载请注明来源

http://blog.csdn.net/myhaspl/

(2)C程序执行

C语言的源代码被翻译成若干行汇编代码,由几个简单的指令组成的汇编代码生成二进制文件,执行这个二进制文件,完成了helloworld的执行。

汇编语言中用的较多助记符是movl、addl、subl

movl完成数据的复制,而addl完成数据的加法,subl完成数据的减法。

这3个助记符的语法格式是:

助记符 源数据 目标数据

比如,对于这段静态分配变量的汇编代码:

myvalue:

.long 190

mess:

.ascii “hello”

通过addl与movl可以完成将myvalue指示的long类型变量190加100,然后减20的功能。

movl myvalue,%ebx

addl $100,%ebx

subl $20,%ebx

movl %ebx,myvalue


汇编语言的代码放在了.text段中,分析上面的helloworld的反汇编代码中一段:

.text

.p2align 4,,15

.globl main

.type main, @function

globl 命令指定了main函数为入口函数(程序启动时执行的函数),然后接着在后面定义了main函数的组成:

main:

leal 4(%esp), %ecx

andl $-16, %esp

pushl -4(%ecx)

pushl %ebp

movl %esp, %ebp

pushl %ecx

subl $4, %esp

movl $.LC0, (%esp)

call puts

movl $0, %eax

addl $4, %esp

popl %ecx

popl %ebp

leal -4(%ecx), %esp

ret

.size main, .-main

.ident "GCC: (GNU) 4.2.1 20070831 patched [FreeBSD]"

.section .note.GNU-stack,"",@progbits

观察这些汇编代码,里面充斥着pushl、popl、movl、subl与addl等助记符,C程序最终就是通过复制、入栈、出栈、加法、减法等简单操作来完成执行的。注意观察这些代码中的如下几行:

leal 4(%esp), %ecx

andl $-16, %esp

pushl -4(%ecx)

pushl %ebp

movl %esp, %ebp

pushl %ecx

subl $4, %esp

movl $.LC0, (%esp)

call puts

C语句的print(“helloworld”)输出字符串就是通过上述几行实现的,除开最后一行call puts(call指令完成调用C语言的puts函数输出字符串的功能,puts函数向终端输出一个字符串,其唯一的参数是char *str,str表示需要输出的字符串)外,其它行做的所有工作就是将调用puts函数的唯一参数(指向字符串”helloworld”地址的标示“.LC0”)的放入堆栈中,以供puts函数调用,倒数第二行将.LC0标记的地址复制到当前堆栈的栈顶,前面几行分配堆栈,调整栈顶指针,将需要保存的寄存器入栈(因为调用puts函数会破坏现有寄存器的值,称之为保存现场),当puts函数完成后,会将入栈的寄存器值弹回各自的寄存器中(称之为恢复现场)。


】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇glsl着色器(c语言) 下一篇[Objective-C]OC中文件读取类(NSF..

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容: