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["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)
}