像冨樫義博那樣拖稿讓人非常討厭, 我喜歡荒木飛呂彥的出稿速度, 搞不好他真的有天堂之門, 我也希望擁有天堂之門的能力, 酷阿!
廢話說太多, 來看這兩個例子, 透過例子來理解 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 帳號。