awkasm: add bit instructions and refine
This commit is contained in:
parent
61d3688581
commit
cb59338554
53
host/asm.awk
53
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)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user