Linux0.11 get_base问题分析
在进行Linux0.11实验的时候发现一个问题,记录一下
static inline unsigned long _get_base(char * addr) { 0: 83 ec 10 sub $0x10,%esp __asm__("movb %3,%%dh\n\t" "movb %2,%%dl\n\t" "shll $16,%%edx\n\t" "movw %1,%%dx" :"=d" (__base) :"m" (*((addr)+2)), 3: 8b 44 24 14 mov 0x14(%esp),%eax 7: 83 c0 02 add $0x2,%eax
//以上的语句准备*((addr)+2)的参数,存放在eax寄存器中 "m" (*((addr)+4)), a: 8b 54 24 14 mov 0x14(%esp),%edx e: 83 c2 04 add $0x4,%edx
//以上的语句准备*((addr)+4)的参数,存放在edx寄存器中 "m" (*((addr)+7))); 11: 8b 4c 24 14 mov 0x14(%esp),%ecx 15: 83 c1 07 add $0x7,%ecx
//以上的语句准备*((addr)+7)的参数,存放在ecx寄存器中 static inline unsigned long _get_base(char * addr) { unsigned long __base; __asm__("movb %3,%%dh\n\t" 18: 8a 31 mov (%ecx),%dh
//edx保存*(addr+4)的数据 1a: 8a 12 mov (%edx),%dl
//由于上面的指令edx已经损坏 1c: c1 e2 10 shl $0x10,%edx 1f: 66 8b 10 mov (%eax),%dx 22: 89 d0 mov %edx,%eax 24: 89 44 24 0c mov %eax,0xc(%esp) "movw %1,%%dx" :"=d" (__base) :"m" (*((addr)+2)), "m" (*((addr)+4)), "m" (*((addr)+7))); return __base; 28: 8b 44 24 0c mov 0xc(%esp),%eax } 2c: 83 c4 10 add $0x10,%esp 2f: c3 ret /* 如上是原函数的实现方法,编译出来有问题,经过分析原因在红色字体
* 第一条指令已经将第二条指令的操作数改变,导致edx的结果出现问题,
* 这个可能和gcc的版本号有关系,总之,这个是可能出问题
*
* 代码修改入下,将红色字体,修饰 =&d 保证输出寄存器edx独占,
* 从而保证正确的结果
* 从下面的代码可以看到*((addr)+4)的参数存放在ebx中.
* 不知道有没有方法可以从gcc的编译参数上解决此类问题
* 因为这样的问题太隐蔽了,几乎不能找到
*
*/ static inline unsigned long _get_base(char * addr) { 0: 53 push %ebx 1: 83 ec 10 sub $0x10,%esp __asm__("movb %3,%%dh\n\t" "movb %2,%%dl\n\t" "shll $16,%%edx\n\t" "movw %1,%%dx" :"=&d" (__base) :"m" (*((addr)+2)), 4: 8b 44 24 18 mov 0x18(%esp),%eax 8: 83 c0 02 add $0x2,%eax "m" (*((addr)+4)), b: 8b 54 24 18 mov 0x18(%esp),%edx f: 8d 5a 04 lea 0x4(%edx),%ebx
//以上的语句准备*((addr)+4)的参数,存放在ebx寄存器中 "m" (*((addr)+7))); 12: 8b 4c 24 18 mov 0x18(%esp),%ecx 16: 83 c1 07 add $0x7,%ecx static inline unsigned long _get_base(char * addr) { unsigned long __base; __asm__("movb %3,%%dh\n\t" 19: 8a 31 mov (%ecx),%dh 1b: 8a 13 mov (%ebx),%dl 1d: c1 e2 10 shl $0x10,%edx 20: 66 8b 10 mov (%eax),%dx 23: 89 d0 mov %edx,%eax 25: 89 44 24 0c mov %eax,0xc(%esp) "movw %1,%%dx" :"=&d" (__base) :"m" (*((addr)+2)), "m" (*((addr)+4)), "m" (*((addr)+7))); return __base; 29: 8b 44 24 0c mov 0xc(%esp),%eax } 2d: 83 c4 10 add $0x10,%esp 30: 5b pop %ebx 31: c3 ret
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律