您的位置:首页 > 编程语言 > C语言/C++

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

2015-12-09 10:26 429 查看
一,研究过程:

在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值是一样的,就是打印的段地址和加载到内存中的段地址数据不同!其原因为何?此问题有待于深一步的研究!!!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: