|
主题 : : 【砖头】综合研究试验2---使用寄存器 [待解决] |
回复[ 11次 ]
点击[ 1437次 ] | |
|
|
|
|
[帖 主]
[ 发表时间:2009-03-19 10:07 ]
[引用]
[回复]
[ top ] | |
荣誉值:61
信誉值:4
注册日期:2008-10-14 16:29 |
在前面,根据教材上的步骤,搭建了一个简易的C语言开发环境。然后,我们开始去对我们第一个问题进行研究。
先思考:
C语言编程能不使用变量么?
我的思考:(参考书中的一些提示)
首先,我们得明白,变量是干什么用的。对了,就是在程序运行的时候存储数据的。那么不用变量存储数据行不行呢?!当然行了,前面的汇编学习过程中,我们从来不用变量的。
那我们用什么了?寄存器和内存啊!!所以,从理论上来说,如果C语言支持对寄存器和内存的直接支配,我们就有可能不用变量来编写C程序(当然,为了说明问题,我们值编写一些简单的小程序来说明问题就OK了)。
这个“研究试验2”就是带领我们,通过使用寄存器来深入的理解C程序一些本质。
首先,我们根据教材介绍的寄存器使用方法,进行实践(1)。在我们的简易C环境下,生成ur1.exe,然后debug ur1.exe。我们之前在跟踪汇编程序的时候,我们知道,当我们设置了assume 和 end 标识后,我们就可以找到程序的入口位置了,可是,在这里,我们看不到end,所以,我们也不知道程序的入口。但是,我认为,既然main函数能被运行,它肯定是在代码段的。本来以为,debug加载后,U命令一开始就应该是main的代码的,因为我一直认为main是C程序运行的开始。不过,当我debug加载后,一看,就蒙了。不是那么回事。一开始U命令看到的都是写莫名其妙的汇编指令,我都开始怀疑,main是不是在代码段了。错了一个想法了,不能这么轻易的就认为自己的另一个想法也是错的,然后,我就开始发挥不怕苦不怕累的优良作风,我跟你U到底了。
双眼瞪圆了看,只要看到类似 mov reg,data的代码就看看是不是和main中的指令作用一样。经过一份苦痛的挣扎,终于找到了如下的汇编指令部分
1547:01FB 8BEC MOV BP,SP
1547:01FD B80100 MOV AX,0001
1547:0200 BB0100 MOV BX,0001
1547:0203 B90200 MOV CX,0002
1547:0206 8BC3 MOV AX,BX
1547:0208 03C1 ADD AX,CX
1547:020A 8AE3 MOV AH,BL
1547:020C 02E1 ADD AH,CL
1547:020E 8AC7 MOV AL,BH
1547:0210 02C5 ADD AL,CH
哈哈,终于找到了吧。小样!说明俺的推理对了一半。呵呵。
现在main的代码找到了,地址是1547:01FB。这个结论还没有高兴两分钟,就发现自己又错了。这不是main的起始地址。晕~~~
接着往下学,把打印main地址的那段程序运行了一下,发现打印出来的数据是1fa。也就是说,main的偏移地址应该是01faH。然后回头看了一下之前跟踪的url.exe的U命令结果,发现,01faH处开始的地方还有两条指令,到底是干什么的呢?仔细看看这段汇编代码
1547:01FA 55 PUSH BP
1547:01FB 8BEC MOV BP,SP
1547:01FD B80100 MOV AX,0001
1547:0200 BB0100 MOV BX,0001
1547:0203 B90200 MOV CX,0002
1547:0206 8BC3 MOV AX,BX
1547:0208 03C1 ADD AX,CX
1547:020A 8AE3 MOV AH,BL
1547:020C 02E1 ADD AH,CL
1547:020E 8AC7 MOV AL,BH
1547:0210 02C5 ADD AL,CH
1547:0212 5D POP BP
1547:0213 C3 RET
突然发现,这么像我们写的汇编子程序的样子
main:
push ..
...
pop ..
ret
难道.....难道main函数只是一个子程序,是一个被别的代码部分调用的子程序??如果是这样的话,那么main就相当于一个子程序的标号(子程序名),也就能解释为什么我们debug后U命令一开始看到的指令不是main函数中的指令了,还能够解释为什么能够使用用printf打印出main的偏移地址来了。到底是不是呢?接着往下看。
教程接下来的讲解果真提到了01faH偏移地址处的两条指令了,不过,知识简单的说理解是函数的特殊设置就行了。我想了想,其实,很像我们写子程序的那个原则,只在子程序中临时使用的寄存器应该先push,退出前再pop,为的是在使用的过程中不影响该寄存器的原有值。这里先思考到这,我们看看最后的任务给我们的提示。
最后,我们抱着“c语言将函数实现为汇编子程序”的猜想,去研究书中的那个代码。如果,正如我们假设的那样,那么在main函数中调用f()的地方,应该是一个call指令,这个指令的地址指向的是f的代码部分,根据前面对于c中函数对应汇编代码的格式来说,那个f的代码应该类似如下
push bp
mov bp,sp
mov ...
add ...
popbp
ret
那我们就带着我们的结论,去看看吧。debug中U命令查看 偏移地址01faH处的汇编指令如下:
1547:01FA 55 PUSH BP
1547:01FB 8BEC MOV BP,SP
1547:01FD B80100 MOV AX,0001
1547:0200 BB0100 MOV BX,0001
1547:0203 B90200 MOV CX,0002
1547:0206 E80200 CALL 020B ;调用f了。哈哈
1547:0209 5D POP BP
1547:020A C3 RET
1547:020B 55 PUSH BP ;020B就是我们猜想的那样。爽!!
1547:020C 8BEC MOV BP,SP
1547:020E 8BC3 MOV AX,BX
1547:0210 03C1 ADD AX,CX
1547:0212 5D POP BP
1547:0213 C3 RET
跟我们的结论那是相当的一致,说明什么?说明C语言中的函数就是对应的汇编语言的子程序。
那么我们就可以把前面这几个含糊的结论总结一下了。
(1)main函数在代码段中。
(2)main函数也是一个被调用的函数,所以,推断,C语言真正的入口不是main,main函数只是那个入口函数的一个call的函数。
(3)在C语言中,函数的实现其实就是对应着汇编语言中的子程序。所以,C程序的运行本质还是汇编那一套。
最后想说的就是:汇编,真TM牛!!(说到这突然想起了,汇编网C教程中第一个用汇编做的C启动代码好像就是在main函数之前进行内存等的分配操作,怪不得main函数不是C程序真正的开始呢。哈哈哈。这回知道了,为什么说要学好后面的C课程要把这个综合研究给整明白了的道理啦。兄弟们啊,一定要借我这前车之鉴啊,不要跟我一样再走弯路喽!)
====================
这次是体会寄存器操作数据,理解了C语言的一些本质的东西,当初没好好学习这一章真是白瞎了。兄弟们一定要好好学习这张的内容啊。
下一节研究内容还是属于不用变量编程的范畴:使用内存空间
准备中... | | |
|
|
|
|
[第1楼]
[ 回复时间:2009-03-20 15:01 ]
[引用]
[回复]
[ top ] | |
荣誉值:152
信誉值:3
注册日期:2008-01-24 21:26 |
|
|
|
|
|
[第2楼]
[ 回复时间:2009-06-02 15:07 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:0
注册日期:2009-04-13 07:29 |
把打印main地址的那段程序运行了一下,发现打印出来的数据是1fa
使用C编译器吗 | | |
|
|
|
|
[第3楼]
[ 回复时间:2009-06-02 15:11 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:0
注册日期:2009-04-13 07:29 |
|
|
|
|
|
[第4楼]
[ 回复时间:2009-06-30 23:21 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:4
注册日期:2009-06-01 21:42 |
|
|
|
|
|
[第5楼]
[ 回复时间:2009-10-30 16:53 ]
[引用]
[回复]
[ top ] | |
荣誉值:169
信誉值:0
注册日期:2008-08-19 16:07 |
|
|
|
|
|
[第6楼]
[ 回复时间:2012-01-01 19:18 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:0
注册日期:2011-12-01 13:02 |
好文章:
(2)main函数也是一个被调用的函数,所以,推断,C语言真正的入口不是main,main函数只是那个入口函数的一个call的函数。
请指教:C语言真正的入口是什么? | | |
|
|
|
|
[第7楼]
[ 回复时间:2012-01-01 22:30 ]
[引用]
[回复]
[ top ] | |
荣誉值:405
信誉值:0
注册日期:2008-01-19 14:51 |
回复6楼:如果你看完这章节的内容应该就明白C语言真正的入口是在c0s.obj中。 | | |
|
|
|
|
[第8楼]
[ 回复时间:2012-03-13 10:44 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:0
注册日期:2012-01-05 18:58 |
这么多我都想不到唉,看了之后才有恍然大悟的感觉,楼主好牛气。。。 | | |
|
|
|
|
[第9楼]
[ 回复时间:2012-03-13 23:32 ]
[引用]
[回复]
[ top ] | |
荣誉值:405
信誉值:0
注册日期:2008-01-19 14:51 |
综合研究包含的内容其实很广很深,需要反复深入学习研究。 | | |
|
|
|
|
[第10楼]
[ 回复时间:2018-01-30 13:44 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:0
注册日期:2018-01-30 13:44 |
|
|
|
|
|
[第11楼]
[ 回复时间:2022-07-24 10:04 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:0
注册日期:2018-10-13 21:08 |
|