awkasm: add bit instructions and refine

This commit is contained in:
Nero 2023-01-05 13:08:58 +00:00
parent 61d3688581
commit cb59338554
1 changed files with 39 additions and 14 deletions

View File

@ -53,6 +53,15 @@ BEGIN {
alu["sub"]=5 alu["sub"]=5
alu["xor"]=6 alu["xor"]=6
alu["cmp"]=7 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 # near conditional jumps
ops_rel8["jo"]=112+0 ops_rel8["jo"]=112+0
ops_rel8["jno"]=112+1 ops_rel8["jno"]=112+1
@ -161,9 +170,11 @@ function expr(str) {
} }
} else if (match(ep[k], /^[0-9]/)) { } else if (match(ep[k], /^[0-9]/)) {
if (match(ep[k], /h$/)) { if (match(ep[k], /h$/)) {
ep[i]="0x" ep[k] ep[k]="0x" ep[k]
} }
val = val + sign*int(ep[k]) val = val + sign*int(ep[k])
} else if (ep[k] == "$") {
val = val + sign*pos
} else if (ep[k] in sym) { } else if (ep[k] in sym) {
val = val + sign*sym[ep[k]] val = val + sign*sym[ep[k]]
} else if (ep[k] in prevsym) { } else if (ep[k] in prevsym) {
@ -253,16 +264,19 @@ function push_op_modrm(opcode) {
} else if (rm2 && wordop && op1 in r16) { } else if (rm2 && wordop && op1 in r16) {
push_byte(opcode+2+1) push_byte(opcode+2+1)
push_modrm(op2, r16[op1], r16) push_modrm(op2, r16[op1], r16)
} else {
return 0
} }
return 1
} }
# common encoding: one operand encoded as modrm with fixed spare field # common encoding: one operand encoded as modrm with fixed spare field
# operand can be byte or word, encoded in last bit of opcode # operand can be byte or word, encoded in last bit of opcode
function push_op_fixed_spare(opcode, spare) { function push_op_fixed_spare(opcode, spare) {
if (byteop) { if (op1 in r8 || (substr(op1,1,1)=="[" && byteop) ) {
push_byte(opcode) push_byte(opcode)
push_modrm(op1, spare, r8) push_modrm(op1, spare, r8)
return 1 return 1
} else if (wordop) { } else if (op1 in r16 || (substr(op1,1,1)=="[" && wordop) ) {
push_byte(opcode+1) push_byte(opcode+1)
push_modrm(op1, spare, r16) push_modrm(op1, spare, r16)
return 2 return 2
@ -306,9 +320,9 @@ $2=="sym" {
} }
# take note if we got a instruction size specifier # take note if we got a instruction size specifier
op=$(opn) op=$(opn)
if (op in prefix) { while (op in prefix) {
push_byte(prefix[op]) push_byte(prefix[op])
opn=opn+1 opn++
op=$(opn) op=$(opn)
} }
@ -378,6 +392,15 @@ op=="equ" {
val=crit(a[1]) val=crit(a[1])
submit(val);next 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" { op=="db" {
for(i=1;i<=c;i++) { for(i=1;i<=c;i++) {
if (substr(a[i],1,1)=="\"") { if (substr(a[i],1,1)=="\"") {
@ -392,8 +415,7 @@ op=="dw" {
} }
# arithmetics: ADD, SUB, XOR etc # arithmetics: ADD, SUB, XOR etc
op in alu { op in alu {
push_op_modrm(alu[op]*8) if (!push_op_modrm(alu[op]*8)) {
if (!hex) {
size=push_op_fixed_spare(0x80, alu[op]) size=push_op_fixed_spare(0x80, alu[op])
if (size==1) { if (size==1) {
push_byte(imm(op2)) 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 # no idea why this made this extra, this is a AND without storing the result
op=="test" { op=="test" {
push_op_modrm(132) # 84 if (!push_op_modrm(132)) { # 84
if (!hex) {
size=push_op_fixed_spare(246, 0) size=push_op_fixed_spare(246, 0)
if (size==1) { if (size==1) {
push_byte(imm(op2)) 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 { op=="inc" && rm1 {
push_op_fixed_spare(254, 0) # FE /0 push_op_fixed_spare(254, 0) # FE /0
} }
@ -473,10 +498,10 @@ op=="int" { # CD
} }
op=="jmp" { op=="jmp" {
val=imm(op1)-(pos+2) val=imm(op1)-(pos+2)
if (val>-127 && val<128 && ecrit) { if (!wordop || (val>-127 && val<128 && ecrit)) {
push_byte(235) push_byte(235)
push_signed_byte(val) push_signed_byte(val)
} else { } else if(wordop) {
push_byte(233) push_byte(233)
push_word(val-1) push_word(val-1)
} }