assembly.jc 2019-4-27 15:34
不知不覺這個 topic 寫左 4 個星期,上次完成左 assemble 部份,終於可以 compile d binary 出來做測試,之前說了,test 的方法是比較 Masm 和 Nasm compile 出來的 binary。
首先比較的是 MASM。但在比對過程中,發覺 MASM 的 Encoding 政策都幾混亂下,可能唔同部份由唔同 programmer 負責,中間又無人協調,結果出現不一致的情況。此話怎說呢?大家都知,一條條 assemble 的 instruction,compile 之後都會變成 binary,例如:
add al, ah
compile 之後變成: 02C4
add [bx], al
就變成: 0007
其中,
00, 02 代表 add,
C4 代表 (al, ah),
07 代表 ([bx], al)。
問題來了,當 cpu 接收到 02C4 時,它如何知道將相加的結果放回 al, 而唔係 ah 呢? 沒錯,答案是...
00, 02,點解要用 2 個 code 代表 add 呢? 原因是 02 代表將運算的結果放回 register,00 就將結果放回其他 "地方"。看看 00, 02 的 binary:
00 = 0000 0000
02 = 0000 0010
其中,第 7 個 bit 叫做 direction bit。1 = 將運算的結果放回 register
Okay? 看看 add al, ah,再看看上面的解釋 「將運算的結果放回 register」,好明顯 ,在你我眼中,al, ah 都是 register,那又回到上面的問題,相加的結果放那裡??
答案係 al,此話怎講? 再看看
C4 = 11 000 100
所謂的 mod r/m reg,可分成三部份:
2 bit | 3 bit | 3 bit
mod | reg |r/m
其中
mod = mode (暫時可以不理)
reg = register
r/m = register or memory
在 cpu 眼中,在 reg 欄位才是 register,在 r/m 欄位的叫做 EA: effective address,EA 包含了 register 和 memory。Okay,在 direction bit 和 mod r/m reg 的配合下,我們終於知道將運算結果放到那裡了。現在問題是,當你 encode
add al, ah
時,到底將 al 當成 register 還是 EA 呢?如果當成 EA,那 add 就 encode 成 00,register 就 encode 成 02。其實二種方法都可行。如果將 add al, ah 一般化成
add op1, op2
那可簡化成一條簡單的規則:
當 op1 是 register 時,direction bit 就是 1,否則就是 0。
MASM 對 add 的處理就用了這規則,但當 encode cmp al, ah 時,又放棄這規則,把 al 當成 EA,ah 當成 register。但但是,cmp ax, bx 又採用返上面的規則,即 ax 當成 register,bx 當 EA。
這方面 NASM 可能做得比較好,因為就以上幾個 instructions ,我在 NASM 上測試了一下,NASM 沒有這情況,它都採取統一的規則: 當 op1, op2 都是 Register,op1 當成 EA。但 NASM 未有全面測試,要到全面測試完結才有正確的結論。
[[i] 本帖最後由 assembly.jc 於 2019-4-27 03:53 PM 編輯 [/i]]
assembly.jc 2019-5-4 15:50
終於測試完! 最終都係放棄用 MASM 做參考,改用 NASM,NASM 基本上無唔一致的地方,generate 出來的萬多 instructions 好順利咁完成比對。
但可惜的是,比對唔到 far call, jmp,即係 call, jmp 32 bit operand,因為 NASM 生成的 binary是針對 32 bit CPU 的,如:
call dword [bx]
8086 16 bit 嘅 CPU encode: FF1F,但 32 bit 嘅 CPU encode: 66 FF17,66 就是所謂 operand-size override prefix,80386 之後才有,意思是用 ebx 中的 bx 部份。
而且,FF17 唔係 FAR call,FF1F 才是,這不是 NASM 的錯,因為 32 bit 對於 32 bit 嘅 CPU 來說是 near call。就算用左 [BITS 16],結果都係一樣。我唔知有什麼方法解決,結果無試到 far call/jmp。
有興趣可看看。
[[i] 本帖最後由 assembly.jc 於 2023-10-22 03:37 編輯 [/i]]
sswroom 2019-5-4 16:08
[quote]原帖由 [i]assembly.jc[/i] 於 2019-5-4 03:50 PM 發表 [url=https://computer.discuss.com.hk/redirect.php?goto=findpost&pid=498778381&ptid=28183178][img]https://computer.discuss.com.hk/images/common/back.gif[/img][/url]
終於測試完! 最終都係放棄用 MASM 做參考,改用 NASM,NASM 基本上無唔一致的地方,generate 出來的萬多 instructions 好順利咁完成比對。
但可惜的是,比對唔到 far call, jmp,即係 call, jmp 32 bit operand,因為 NASM 生成的 binary是針對 32 bit CPU 的,如:
call dword
80 ... [/quote]REP MOVSB
REP MOVSW
這2個指令?
INT 3 = CC 還是 CD 03?
assembly.jc 2019-5-4 17:55
[quote]原帖由 [i]sswroom[/i] 於 2019-5-4 04:08 PM 發表 [url=https://computer.discuss.com.hk/redirect.php?goto=findpost&pid=498779100&ptid=28183178][img]https://computer.discuss.com.hk/images/common/back.gif[/img][/url]
REP MOVSB
REP MOVSW
這2個指令?
INT 3 = CC 還是 CD 03? [/quote]
REP LODSB
REPE CMPSB
REPZ CMPSB
REPNZ CMPSB
REPNE CMPSB
主要試 rep, repe ... prefix encoding。rep 後面的 mnemonic 應該不會影響 encoding的。
Int3 應該是 CC 的。但 NASM 出 CD 03,我跟了它...