像冨樫義博那樣拖稿讓人非常討厭, 我喜歡荒木飛呂彥的出稿速度, 搞不好他真的有天堂之門, 我也希望擁有天堂之門的能力, 酷阿!
廢話說太多, 來看這兩個例子, 透過例子來理解 machine code 是最好的方法了, 所以這系列我都會以例子來說明:
- base register address mode + displacement8
 - base register address mode + displacement32
 
用 32bit 組譯出來的 machine code。
#practice x86 machine code #.code16 .code32 .text .global begin begin: sub 126(%edi), %edi
intel syntax: sub edi, [edi+126]
註: 這個例子是 32bit mode
opcode: 2b
http://css.csail.mit.edu/6.858/2011/readings/i386/SUB.htm
2B /r SUB r32,r/m32 2/7 Subtract dword register from r/m dword
modrm: 7f -> 0111 1111 -> 01 111 111
mod: 01
reg: 111 (edi)
r/m: 111
| [EAX]+disp83 | 000 | 
| [ECX]+disp8 | 001 | 
| [EDX]+disp8 | 010 | 
| [EBX]+disp8 | 011 | 
| [--]+disp8 | 100 | 
| [EBP]+disp8 | 101 | 
| [ESI]+disp8 | 110 | 
| [EDI]+disp8 | 111 | 
查表得到 (這個表在 intel 手冊查得, 有分 16/32 bit 兩種不同表格)
mod:01, r/m:111 => [EDI]+disp8 => [EDI] + 0x7e => [EDI + 126]
2b 7f 7e 就是這麼來的。
#practice x86 machine code #.code16 .code32 .text .global begin begin: add 0x12345678(%edi), %esiintel syntax: add esi, [edi+12345678h]
add opcode: http://css.csail.mit.edu/6.858/2011/readings/i386/ADD.htm
03 /r ADD r32,r/m32 2/6 Add r/m dword to dword register
modrm: b7 -> 1011 0111 -> 10 110 111
mod:10
reg: 110 (esi)
r/m: 111
| [EAX]+disp32 | 000 | 
| [ECX]+disp32 | 001 | 
| [EDX]+disp32 | 010 | 
| [EBX]+disp32 | 011 | 
| [--][--]+ disp32 | 100 | 
| [EBP]+disp32 | 101 | 
| [ESI]+disp32 | 110 | 
| [EDI]+disp32 | 111 | 
查表得到
mod: 10
r/m: 111
=> [EDI]+disp32 => EDI + 78 56 34 12 => [EDI + 0x 12345678]
來看個 16 bit 範例:
section:disp(base,index,scale)
# practice x86 machine code .code16 .text .global begin begin: add 0x12(%bx, %si, 1), %si
03 70 12 add 0x12(%bx,%si),%si
16bit mode 沒有 scale 這欄位, 所以 1 就被拿掉了, 而 scale 1 和沒有 scale 是一樣的。
modrm: 70 -> 0111 0000 -> 01 110 000
mod: 01
reg: 110 (SI)
r/m: 000
| [BX+SI]+disp8 | 000 | 
| [BX+DI]+disp8 | 001 | 
| [BP+SI]+disp8 | 010 | 
| [BP+DI]+disp8 | 011 | 
| [SI]+disp8 | 100 | 
| [DI]+disp8 | 101 | 
| [BP]+disp8 | 110 | 
| [BX]+disp8 | 111 | 
查表得到
mod: 01
r/m: 000
[BX+SI]+disp8 => [BX+SI] + 0x12
在 16 bit 模式下把 scale factor 改成 2 會怎樣?
# practice x86 machine code .code16 .text .global begin begin: add 0x12(%bx, %si, 2), %si
address_mode.S: Assembler messages: address_mode.S:8: Error: `0x12(%bx,%si,2)' is not a valid base/index expression make: *** [address_mode.o] Error 1
組譯就不會過, 現在你知道為什麼了。
沒有留言:
張貼留言
使用 google 的 reCAPTCHA 驗證碼, 總算可以輕鬆留言了。
我實在受不了 spam 了, 又不想讓大家的眼睛花掉, 只好放棄匿名留言。這是沒辦法中的辦法了。留言的朋友需要有 google 帳號。