From cb593385548aaf7b23760bf271d78e20d4f9b530 Mon Sep 17 00:00:00 2001 From: Nero <41307858+nero@users.noreply.github.com> Date: Thu, 5 Jan 2023 13:08:58 +0000 Subject: [PATCH] awkasm: add bit instructions and refine --- host/asm.awk | 53 ++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 39 insertions(+), 14 deletions(-) diff --git a/host/asm.awk b/host/asm.awk index 105a78b..f57efdc 100644 --- a/host/asm.awk +++ b/host/asm.awk @@ -53,6 +53,15 @@ BEGIN { alu["sub"]=5 alu["xor"]=6 alu["cmp"]=7 + # bit instructions + grp2["rol"]=0 + grp2["ror"]=1 + grp2["rcl"]=2 + grp2["rcr"]=3 + grp2["shl"]=4 + grp2["sal"]=4 + grp2["shr"]=5 + grp2["sar"]=7 # near conditional jumps ops_rel8["jo"]=112+0 ops_rel8["jno"]=112+1 @@ -161,9 +170,11 @@ function expr(str) { } } else if (match(ep[k], /^[0-9]/)) { if (match(ep[k], /h$/)) { - ep[i]="0x" ep[k] + ep[k]="0x" ep[k] } val = val + sign*int(ep[k]) + } else if (ep[k] == "$") { + val = val + sign*pos } else if (ep[k] in sym) { val = val + sign*sym[ep[k]] } else if (ep[k] in prevsym) { @@ -253,16 +264,19 @@ function push_op_modrm(opcode) { } else if (rm2 && wordop && op1 in r16) { push_byte(opcode+2+1) push_modrm(op2, r16[op1], r16) + } else { + return 0 } + return 1 } # common encoding: one operand encoded as modrm with fixed spare field # operand can be byte or word, encoded in last bit of opcode function push_op_fixed_spare(opcode, spare) { - if (byteop) { + if (op1 in r8 || (substr(op1,1,1)=="[" && byteop) ) { push_byte(opcode) push_modrm(op1, spare, r8) return 1 - } else if (wordop) { + } else if (op1 in r16 || (substr(op1,1,1)=="[" && wordop) ) { push_byte(opcode+1) push_modrm(op1, spare, r16) return 2 @@ -306,9 +320,9 @@ $2=="sym" { } # take note if we got a instruction size specifier op=$(opn) - if (op in prefix) { + while (op in prefix) { push_byte(prefix[op]) - opn=opn+1 + opn++ op=$(opn) } @@ -378,6 +392,15 @@ op=="equ" { val=crit(a[1]) submit(val);next } +op==".space" { + len=crit(a[1]) + val=0 + if (a[2]) val=crit(a[2]) + for(i=1;i<=len;i++) { + push_byte(val) + } + submit(pos);next +} op=="db" { for(i=1;i<=c;i++) { if (substr(a[i],1,1)=="\"") { @@ -392,8 +415,7 @@ op=="dw" { } # arithmetics: ADD, SUB, XOR etc op in alu { - push_op_modrm(alu[op]*8) - if (!hex) { + if (!push_op_modrm(alu[op]*8)) { size=push_op_fixed_spare(0x80, alu[op]) if (size==1) { push_byte(imm(op2)) @@ -402,10 +424,16 @@ op in alu { } } } +# Group 2 +op in grp2 && op2=="1" { + push_op_fixed_spare(208, grp2[op]) +} +op in grp2 && op2=="cl" { + push_op_fixed_spare(210, grp2[op]) +} # no idea why this made this extra, this is a AND without storing the result op=="test" { - push_op_modrm(132) # 84 - if (!hex) { + if (!push_op_modrm(132)) { # 84 size=push_op_fixed_spare(246, 0) if (size==1) { push_byte(imm(op2)) @@ -414,9 +442,6 @@ op=="test" { } } } -op=="sar" && op2=="1" { - push_op_fixed_spare(208, 0) # D0 /0 -} op=="inc" && rm1 { push_op_fixed_spare(254, 0) # FE /0 } @@ -473,10 +498,10 @@ op=="int" { # CD } op=="jmp" { val=imm(op1)-(pos+2) - if (val>-127 && val<128 && ecrit) { + if (!wordop || (val>-127 && val<128 && ecrit)) { push_byte(235) push_signed_byte(val) - } else { + } else if(wordop) { push_byte(233) push_word(val-1) }