Chinaunix首页 | 论坛 | 博客
  • 博客访问: 340485
  • 博文数量: 88
  • 博客积分: 2011
  • 博客等级: 大尉
  • 技术积分: 885
  • 用 户 组: 普通用户
  • 注册时间: 2010-05-21 14:50
文章分类

全部博文(88)

文章存档

2010年(88)

我的朋友

分类: LINUX

2010-09-16 13:39:53

转载看雪上的一个讨论

问:

在罗聪的网站(当然在很多地方都能看到)我看到关于代码重定位的代码,即
    call nStart
nStart:
    pop ebp
    sub ebp,offset nStart ;对这句代码我有一点疑惑
    是这样的,call执行的操作应当是将call的下一条指令(在此处即为"pop ebx")的地址压入堆栈,然后jmp到nStart,之后执行pop ebp,那么现在ebp中
    的内容就应当是"pop ebp"这句代码的地址,那么下一句代码"sub ebp,offset nStart"的作用又是什么呢?我的理解是ebp减去nStart标号的地址,而
    nStart标号的地址与"pop ebx"这句的地址应该相同吧,那么最后ebp的值就总是为0(并且我认为无论将这段代码放到何处,ebp总会为0),代码不就失去  
    了作用么?
    小弟资质愚钝,希望各位大哥赐教。

答:

假如下面那段代码是在自己程序中的代码。因为pop ebp的地址也是00401005,这时sub ebp,00401005的结果ebp就是等于0了。不过现在假如将这段编译好的二进制代码拷贝到00402000处运行,你想会怎样?
00401000 call 00401005 ; call nStart
00401005 pop ebp
00401006 sub ebp, 00401005 ; sub ebp,offset nStart

假如将这段代码拷贝到00402000处运行,就会变成如下面这样,你还认为是没用的吗?
00402000 call 00402005
00402005 pop ebp ; ebp == 00402005
00402006 sub ebp, 00401005 ; 注nStart的标号地址在被编译为二进制后就是固定的00401005了,不会再变了,这时你认为ebp还是等于0?

总结一句,编译的时候,标签的地址是固定的,但是call的地址是随着程序所在位置变化的

阅读(1212) | 评论(1) | 转发(0) |
0

上一篇:Linux多级页表

下一篇:ASCII码值表

给主人留下些什么吧!~~

chinaunix网友2010-09-16 16:56:36

很好的, 收藏了 推荐一个博客,提供很多免费软件编程电子书下载: http://free-ebooks.appspot.com