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

复制代码

 

posted on   sudochen  阅读(35)  评论(0编辑  收藏  举报

相关博文:
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律

导航

< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5
点击右上角即可分享
微信分享提示