我最近需要在汇编级调试程序.我没有很多汇编程序经验,所以我想我会编写一些简单的C程序并单步执行它们,以便在我开始调试其他人的代码之前感受一下这种语言.但是,我真的不知道gcc用这两行代码(用-ggdb -O0编译):
items[tail] = i;
tail = (tail+1) % MAX_SIZE;
Run Code Online (Sandbox Code Playgroud)
其中MAX_SIZE #defined为5,i是局部变量(存储在0x8(%ebp)中,我猜).根据gdb,这变为:
0x08048394 <queue+17>: mov 0x8049634,%edx
0x0804839a <queue+23>: mov 0x8(%ebp),%eax
0x0804839d <queue+26>: mov %eax,0x804963c(,%edx,4)
0x080483a4 <queue+33>: mov 0x8049634,%eax
0x080483a9 <queue+38>: lea 0x1(%eax),%ecx
0x080483ac <queue+41>: movl $0x66666667,-0xc(%ebp)
0x080483b3 <queue+48>: mov -0xc(%ebp),%eax
0x080483b6 <queue+51>: imul %ecx
0x080483b8 <queue+53>: sar %edx
0x080483ba <queue+55>: mov %ecx,%eax
0x080483bc <queue+57>: sar $0x1f,%eax
0x080483bf <queue+60>: mov %edx,%ebx
0x080483c1 <queue+62>: sub %eax,%ebx
0x080483c3 <queue+64>: mov %ebx,-0x8(%ebp)
0x080483c6 <queue+67>: mov -0x8(%ebp),%eax
0x080483c9 <queue+70>: shl $0x2,%eax
0x080483cc <queue+73>: add -0x8(%ebp),%eax
0x080483cf <queue+76>: mov %ecx,%edx
0x080483d1 <queue+78>: sub %eax,%edx
0x080483d3 <queue+80>: mov %edx,-0x8(%ebp)
0x080483d6 <queue+83>: mov -0x8(%ebp),%ebx
0x080483d9 <queue+86>: mov %ebx,0x804963
Run Code Online (Sandbox Code Playgroud)
由于0x804963c是项的地址,我可以看到第一行C代码是如何工作的.另外,0x8049634是尾部的地址,所以我猜队列+ 33和队列+38相当于%ecx = tail + 1 ......但我不知道之后发生了什么.谁会想到一个简单的模数可能会这么复杂?
mwe*_*den 14
这是一种避免必须执行更昂贵的除法指令的方法.我第一次遇到这个时也很难过.有趣的是,搜索用于此技巧的神奇数字(在这种情况下0x66666667)通常会给出解释此技巧的结果.(我当时认为这是我必须继续进行的唯一具体事情,因为我没有来源.)
快速搜索给了我这篇博文:http://blog.dkbza.org/2007/09/reverse-engineering-compiler-produced.html它底部有一些有用的链接(包括间接链接到这篇论文)特技).
| 归档时间: |
|
| 查看次数: |
2883 次 |
| 最近记录: |