汇编网首页登录博客注册
aten的学习博客
博客首页博客互动【做检测题】论坛求助

我的博客

个人首页 |  我的文章 |  我的相册 |  我的好友 |  最新访客 |  文章收藏 |  论坛提问 |  友情链接 |  给我留言  
图片载入中
学习动态
友情链接

[2009-04-21 15:13] 推荐博文 研究实验4 不用main函数编程

(1)程序f.c
f()
{
 *(char far *)(0xb8000000+160*10+80)='a';
 *(char far *)(0xb8000000+160*10+80)=2;
}

(1)把程序f.c保存在k:\minic下,对其进行编译,连接。思考相关问题!
问题:1 编译和连接哪个环节会出问题?
        连接时出错!
      2 显示出的错误信息是什么?
        Linker Error:Undefinde symbol'_main'in module c0s
      3 这个错误信息可能与哪个文件相关?
        应该和c0s.obj有关!

(2)用学习汇编语言时使用的link.exe对tc.exe生成的f.obj文件进行连接,生成f.exe。用Debug加载

f.exe。用Debug加载f.exe,察看整个程序的汇编代码。思考相关问题。
问题:1 f.exe的程序代码总共有多少字节?541byte
      2 f.exe的程序能正确返回吗?  不能
      3 f函数的偏移地址是多少?     0
(3)写一个程序m.c

main()
{
 *(char far *)(0xb8000000+160*10+80)='a';
 *(char far *)(0xb8000000+160*10+80)=2;
}
用tc.exe对m.c进行编译,连接,生成m.exe,用Debug察看m.exe整个程序的汇编代码。思考相关的问题。
问题:
1 m.exe的程序代码总共有多少字节?                          4190字节!
2 m.exe能正确返回吗?                                      能
3 m.exe程序中的main函数和f.exe中的f函数的汇编代码有何不同?没有不同

(4)用Debug对m.exe进行跟踪:1.找到对main函数进行调用的指令的地址;2.找到整个程序返回的指令。
1对main函数进行调用的指令的地址为:140e:11a
2整个程序的返回指令如下:
140E:0151 B44C          MOV     AH,4C
140E:0153 8A4602        MOV     AL,[BP+02]
140E:0156 CD21          INT     21

(5)经过上面的现象,猜想main函数调用的指令和程序返回的指令应该是用c0s.obj来的!

(6)用link.exe对k:\minic目录下的c0s.obj进行连接,生成c0s.exe.
用Debug分别察看c0s.exe和m.exe的汇编代码。注意:从头开始察看,两个文件中的程序代码有何相同之处?  看了下两者的代码,进行的操作基本上一样!

(7)用Debug找到m.exe中调用main函数的call指令的偏移地址,从这个偏移地址开始向后察看10条指令;

然后用Debug加载c0s.exe,从相同的偏移地址向后察看10条指令。对两处指令进行对比。
不用处:
K:\minic>debug c0s.exe
-u11a
140E:011A E80000        CALL    011D
140E:011D 50            PUSH    AX
140E:011E E80000        CALL    0121
K:\minic>debug m.exe
-u11a
140E:011A E8DD00        CALL    01FA
140E:011D 50            PUSH    AX
140E:011E E8F700        CALL    0218

(8)从上我们可以看出tc.exe把c0s.obj和用户obj文件一同进行连接,生成exe文件。按照这个方法生成的exe文件中的程序的运行过程如下。
1 c0s.obj里的程序先运行,进行相关的初始化,比如,申请资源,设置DS、SS等寄存器;
2 c0s.obj的程序调用main函数,从此用户程序开始运行;
3 用户程序从main函数返回到c0s.obj的程序中;
4 c0s.lbj的程序接着运行,进行相关原资源释放,环境恢复等工作;
5 c0s.obj的程序调用DOS的int 21h例程4ch号功能,程序返回。
  看来,C程序必须从main函数开始,是C语言的规定,这个规定不是在编译时保证的,也不是连接的时候保证的,而是如下机制保证的:
  首先,C开发系统提供了用户写的应用程序正确运行所必须的初始化和程序返回等相关程序,这些程序

存放在相关的obj文件(比如,c0s.obj)
  其次,需要将这些文件和用户.obj文件一起进行连接,才能生成可正确运行的.exe文件。
  第三,连接在用户.obj文件 前面的由C语言开发系统提供的.obj文件里的程序要对main函数进行调用。
  基于这种机制,我们只要修改c0s.obj,让它调用其他函数,编程时就可以不写main函数了.
  ……
  完成了上面的实验,真正的收获并不是知道了改写c0s.obj编程时就可以不写main函数了,而是整个研究过程体现出来的方法和思想,真的太有所感悟了!对要研究的问题进行一步步细化,设计对比,猜想,验证……。
评论次数(14)  |  浏览次数(41770)  |  类型(汇编作业) |  收藏此文  | 

[  younggay   发表于  2009-04-24 11:40  ]

分析的很好!!

[  游客   发表于  2009-05-22 19:40  ]

向您请教:
(8)从上我们可以看出tc.exe把c0s.obj和用户obj文件一同进行连接,生成exe文件。......
这句话是怎么理解的?如何看出tc.exe把c0s.obj和用户obj文件一同进行连接?具体表现在什么地方?
这是我调试第7步的数据:
F:\dosimg\minic>debug m.exe
-u 11a
13D6:011A E8DD00        CALL    01FA
13D6:011D 50            PUSH    AX
13D6:011E E8F700        CALL    0218
13D6:0121 2E            CS:
13D6:0122 8E1EF801      MOV     DS,[01F8]
13D6:0126 E87C00        CALL    01A5
13D6:0129 0E            PUSH    CS
13D6:012A FF16A201      CALL    [01A2]
13D6:012E 33C0          XOR     AX,AX
13D6:0130 8BF0          MOV     SI,AX
13D6:0132 B92F00        MOV     CX,002F
13D6:0135 90            NOP

F:\dosimg\>debug c0s.exe
-u 11a
13D6:011A E80000        CALL    011D
13D6:011D 50            PUSH    AX
13D6:011E E80000        CALL    0121
13D6:0121 2E            CS:
13D6:0122 8E1EF801      MOV     DS,[01F8]
13D6:0126 E87C00        CALL    01A5
13D6:0129 0E            PUSH    CS
13D6:012A FF169601      CALL    [0196]
13D6:012E 33C0          XOR     AX,AX
13D6:0130 8BF0          MOV     SI,AX
13D6:0132 B92F00        MOV     CX,002F
13D6:0135 90            NOP
个人很愚笨,请您指点一下。

[  keyia   发表于  2009-05-22 19:42  ]

keyia:变成游客了

[  aten   发表于  2009-05-26 22:52  ]

好久没来汇编网了,拿你调试的结果来说吧!
F:\dosimg\>debug c0s.exe 
-u 11a 
13D6:011A E80000        CALL    011D 
13D6:011D 50            PUSH    AX 
13D6:011E E80000        CALL    0121 
这里CAll 011D 就是执行puhs ax,直接往下执行了!注意,这是c0s.obj连接生成的exe文件!再看
F:\dosimg\minic>debug m.exe 
-u 11a 
13D6:011A E8DD00        CALL    01FA 
13D6:011D 50            PUSH    AX 
13D6:011E E8F700        CALL    0218 
这里面 011D往后是不是和只用c0s.obj连接生成的exe文件的指令相同!而CAll 01FA 这里转向哪执行你也知道!说明这把c0s.obj和用户的.obj一同进行连接了!

[  keyia   发表于  2009-05-28 01:32  ]

啊,如梦初醒!万分感谢

[  游客   发表于  2012-06-11 13:31  ]

飘过

 
 请输入验证码  (提示:点击验证码输入框,以获取验证码