《C语言综合研究第2章宣讲会研究报告_20130610_v1.0》 2.docx

一,研究过程:

在main函数中添加语句,使下面的程序可以打印出所有函数的段地址和偏移地址;具体例程如下:

Int  a;

Void  f1(void)

{

A=1;

}

Void  f2(void)

{

A=2;

}

Void f3(void)

{

A=3;

}

Main()

{

int addr=(int)f1;

int  (*P)()=f1;

printf("f1(P) address is:\t%x\n",P);

printf("f1(addr) address is:\t%x\n",addr);

printf("f1 address is:\t\t%x\n",f1);

printf("f2 address is:\t\t%x\n",f2);

printf("f3 address is:\t\t%x\n",f3);

printf("the code segment is:\t%x\n",_CS);

printf("the main segment is:\t%x\n",main);

printf("main:\t%lx\n",(long)main);

printf("f1:\t%lx\n",(long)f1);

printf("f2:\t%lx\n",(long)f2);

printf("f3:\t%lx\n",(long)f3);

}

运行结果:

Debug 2.exe文件查看起反汇编代码如下:

-u 1fa

0B70:01FA C706E6040100  MOV     WORD PTR [04E6],0001

0B70:0200 C3            RET            此处验证f1偏移地址为1fa

0B70:0201 C706E6040200  MOV     WORD PTR [04E6],0002

0B70:0207 C3            RET           此处验证f2其偏移地址为201

0B70:0208 C706E6040300  MOV     WORD PTR [04E6],0003

0B70:020E C3            RET           此处验证f3其偏移地址为208而上述的三个段地址与打印的结果不符;在这里有点小疑问!!!

0B70:020F 56            PUSH    SI    此处为main函数的偏移地址

0B70:0210 57            PUSH    DI

0B70:0211 BEFA01        MOV     SI,01FA

0B70:0214 BFFA01        MOV     DI,01FA

0B70:0217 57            PUSH    DI     此处用栈传送待打印的P(f1)的偏移地址

0B70:0218 B89401        MOV     AX,0194

0B70:021B 50            PUSH    AX

0B70:021C E83F09        CALL    0B5E   调用printf函数打印

0B70:021F 59            POP     CX

0B70:0220 59            POP     CX     以上两句恢复栈平衡

0B70:0221 56            PUSH    SI      此处用栈传送待打印的addr(f1)的偏移地址

0B70:0222 B8AA01        MOV     AX,01AA

0B70:0225 50            PUSH    AX

0B70:0226 E83509        CALL    0B5E   调用printf函数打印

0B70:0229 59            POP     CX

0B70:022A 59            POP     CX     以上两句恢复栈平衡

0B70:022B B8FA01        MOV     AX,01FA

0B70:022E 50            PUSH    AX     此处用栈传送f1的偏移地址

0B70:022F B8C301        MOV     AX,01C3

0B70:0232 50            PUSH    AX

0B70:0233 E82809        CALL    0B5E    调用printf函数打印

0B70:0236 59            POP     CX

0B70:0237 59            POP     CX     以上两句恢复栈平衡

0B70:0238 B80102        MOV     AX,0201

0B70:023B 50            PUSH    AX     此处用栈传送f2的偏移地址

0B70:023C B8D701        MOV     AX,01D7

0B70:023F 50            PUSH    AX

0B70:0240 E81B09        CALL    0B5E    调用printf函数打印

0B70:0243 59            POP     CX

0B70:0244 59            POP     CX      以上两句恢复栈平衡

0B70:0245 B80802        MOV     AX,0208

0B70:0248 50            PUSH    AX     此处用栈传送f3的偏移地址

0B70:0249 B8EB01        MOV     AX,01EB

0B70:024C 50            PUSH    AX

0B70:024D E80E09        CALL    0B5E   调用printf函数打印

0B70:0250 59            POP     CX

0B70:0251 59            POP     CX     以上两句恢复栈平衡

0B70:0252 8CC8          MOV     AX,CS

0B70:0254 50            PUSH    AX    此处用栈传送待打印的_CS的偏移地址

0B70:0255 B8FF01        MOV     AX,01FF

0B70:0258 50            PUSH    AX

0B70:0259 E80209        CALL    0B5E    调用printf函数打印

0B70:025C 59            POP     CX

0B70:025D 59            POP     CX    以上两句恢复栈平衡

0B70:025E B80F02        MOV     AX,020F

0B70:0261 50            PUSH    AX     此处用栈传送待打印的main的偏移地址

0B70:0262 B81802        MOV     AX,0218

0B70:0265 50            PUSH    AX

0B70:0266 E8F508        CALL    0B5E    调用printf函数打印

0B70:0269 59            POP     CX

0B70:026A 59            POP     CX      以上两句恢复栈平衡

0B70:026B 0E            PUSH    CS      因用的是long型打印故首先入栈cs,紧接着下面入栈main的偏移地址

0B70:026C B80F02        MOV     AX,020F

0B70:026F 50            PUSH    AX

0B70:0270 B83102        MOV     AX,0231

0B70:0273 50            PUSH    AX

0B70:0274 E8E708        CALL    0B5E     调用printf函数打印

0B70:0277 83C406        ADD     SP,+06   恢复栈平衡

0B70:027A 0E            PUSH    CS       因用的是long型打印故首先入栈cs,紧接着下面入栈f1的偏移地址

0B70:027B B8FA01        MOV     AX,01FA

0B70:027E 50            PUSH    AX

0B70:027F B83C02        MOV     AX,023C

0B70:0282 50            PUSH    AX

0B70:0283 E8D808        CALL    0B5E      调用printf函数打印

0B70:0286 83C406        ADD     SP,+06    恢复栈平衡

0B70:0289 0E            PUSH    CS        因用的是long型打印故首先入栈cs,紧接着下面入栈f2的偏移地址

0B70:028A B80102        MOV     AX,0201

0B70:028D 50            PUSH    AX

0B70:028E B84502        MOV     AX,0245

0B70:0291 50            PUSH    AX

0B70:0292 E8C908        CALL    0B5E       调用printf函数打印

0B70:0295 83C406        ADD     SP,+06      恢复栈平衡

0B70:0298 0E            PUSH    CS         因用的是long型打印故首先入栈cs,紧接着下面入栈f3的偏移地址

0B70:0299 B80802        MOV     AX,0208

0B70:029C 50            PUSH    AX

0B70:029D B84E02        MOV     AX,024E

0B70:02A0 50            PUSH    AX

0B70:02A1 E8BA08        CALL    0B5E       调用printf函数打印

0B70:02A4 83C406        ADD     SP,+06      恢复栈平衡

0B70:02A7 5F            POP     DI

0B70:02A8 5E            POP     SI          恢复进main时栈平衡

0B70:02A9 C3            RET                 main返回

二,遇到的问题:

在研究的过程当中,打印的段地址与debug中查看到的不一致,在这里有一点疑惑;

三,解决掉的问题:

通过本次的研究知道了如何去打印函数的段地址和偏移地址,在探究时也用了几个不同的方法去打印他们的值,其结果是一样的。

四,研究体会:

通过本次的研究,更加深一步的去了解了子函数和main函数的偏移和段地址的查找方法,因为此代码加载到内存时,其默认的段地址为cs段,故我们在此打印_CS就为这些函数的段地址,此程序有一疑问,偏移地址打印的和debug查看内存cs值是一样的,就是打印的段地址和加载到内存中的段地址数据不同!其原因为何?此问题有待于深一步的研究!!!

时间: 2024-11-03 21:50:20

《C语言综合研究第2章宣讲会研究报告_20130610_v1.0》 2.docx的相关文章

《javascript语言精粹》——第3章

第三章:对象: 属性名字:可以是包括空字符串在内的任意字符串: 属性值:是除undefined值之外的任何值; [1].对象字面量: var obj={}; //空对象 var newobj={ name:"小明", age:17, school:{ class:"一班" } }; 属性名可加引号,也可不加 [2].检索 newobj["name"] //小明 newobj.age  //17  推荐使用.可读性更加好,紧凑 newobj[&qu

《javascript语言精粹》——第4章函数

函数就是对象 [1].函数字面量即(函数表达式)包括四部分: 第一部分:保留字function: 第二部分:函数名称,可有可无: 第三部分:包围在一对小括号的一组参数,参数用逗号隔开: 第四部分:包围在一对花括号的一组语句,是函数的主体: 函数字面量可以出现在任何允许表达式出现的地方. [2].调用有四种调用模式: 除了声明时定义的形参,每个函数接收附加的的参数:this和arguments  ,this的值取决于调用的模式. 第一种:方法调用模式: var aa={ value:0, incr

《数据结构与算法分析:C语言描述》复习——第九章“图论”——无权值的最短路径问题

2014.07.04 18:24 简介: 给定一个有向图,你可以认为每条边长度都是1(所以叫无权值).下面的算法可以求出从特定的起点到终点的最短路径长度. 描述: 从起点出发,根据当前顶点出发的边进行广度优先搜索,直至找到终点即可.如果搜索结束了仍然没有找到终点,那么起点无法到达终点. 实现: 1 // A simple illustration for unweighted shortest path. Graph represented by adjacency matrix. 2 #inc

swift语言实战晋级-第9章 游戏实战-跑酷熊猫-9-10 移除平台与视差滚动

原文:swift语言实战晋级-第9章 游戏实战-跑酷熊猫-9-10 移除平台与视差滚动 9.9 移除场景之外的平台 用为平台是源源不断的产生的,如果不注意销毁,平台就将越积越多,虽然在游戏场景中看不到.几十个还看不出问题,那几万个呢?几百万个呢? 所以我们来看看怎么移除平台,那什么样的平台需要移除呢?又如何移除呢?之前我们也说过,当平台完全移除游戏场景的时候就可以进行移除操作了.需要做两个操作,1从平台工厂类中移除,2从平台数组中移除. 而且,因为平台是一个接一个出现的,所以我们不需要每次都遍历

《C程序设计语言(第2版·新版)》第0章 引言

从这篇开始,按照我的理解,整理Kernigham和Ritchie的<C程序设计语言(第2版·新版)>. 0.1 C C很适合用来编写编译器和操作系统,被称作“系统编程语言”:BCPL语言-->B语言-->C语言: 数据类型:基本(字符,多种长度整型和浮点型):派生(指针,数组,结构,联合):表达式:运算符+操作数,总可以作为语句:指针:提供与具体机器无关的地址算术运算: 控制流结构:语句组,条件判断(if-else),多路选择(switch),终止测试在顶部的循环(while, f

Swift语言实战晋级-第9章 游戏实战-跑酷熊猫-5-6 踩踏平台是怎么炼成的

原文:Swift语言实战晋级-第9章 游戏实战-跑酷熊猫-5-6 踩踏平台是怎么炼成的 在游戏中,有很多分来飞去的平台,这个平台长短不一.如果每种长度都去创建一张图片那是比较繁琐的事情.实际上,我们只用到3张图.分别是平台的,平台的中间部分,平台的右边.关键是平台的中间部分,两张中间部分放在一起能够很好地衔接起来,这样只要增加中间部分的数量就能创建不同长度的平台.那这种图片该怎么制作呢?我们先找一张平台的完整图 然后切出中间部分. 这时候,我们能够发现,两块中间部分能够无缝的拼在一起.那么我们就

「红松教育」2019中级通信工程师「综合能力」第一章划重点啦

今天我们先聊一聊 [综合能力]第一章[通信职业道德] 主要包含以下内容这些内容经过抽丝剥茧 划划重点 大家要掌握的主要就是 原文地址:https://blog.51cto.com/14226733/2413698

王爽-汇编语言-综合研究一-搭建简易C环境

(一) 学习过程: 整个过程分为两个部分: 第一:将TC2.0的环境使用虚拟软盘复制到DOS虚拟机中: 打开WinImage,fileànew,由于TC2.0的环境解压后为2.02M,所以我们在Standard format中选择2.88M. 将TC文件夹放入.保存. 在DOS虚拟机中加载做好的软盘.这时A:\内有TC2.0的所有文件了. 此处援引书中的话: 我们在把一个程序拷贝的一个空的目录后,这个目录下只有这一个程序,然后我们运行它,它可以正确运行,我们就认为这个程序在运行中不需要别的文件.

《Go语言网络编程》第一章:体系

原书地址:http://tumregels.github.io/Network-Programming-with-Go 如果不知道想要构建什么,是不可能创建一个系统的.而且如果不知道它工作的环境,也同样无法构建. GUI程序不同于批处理程序:游戏程序不同于商业程序:分布式程序不同于单机程序. 他们都有自己的方法.一般模式和问题,都有各自的常见问题和常见解决方案. 本章讨论分布式系统高层架构层面的一些内容.有多种方式看待这样的系统,而且其中的许多问题已经被解决. 协议层 分布式系统很难!其中涉及到