《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     此处用栈传送待打印的Pf1)的偏移地址

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      此处用栈传送待打印的addrf1)的偏移地址

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值是一样的,就是打印的段地址和加载到内存中的段地址数据不同!其原因为何?此问题有待于深一步的研究!!!

posted on 2015-12-09 10:26  我很勇  阅读(153)  评论(0编辑  收藏  举报

导航