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["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)
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user