diff options
| -rw-r--r-- | quine.asm | 19 |
1 files changed, 11 insertions, 8 deletions
diff --git a/quine.asm b/quine.asm index 3136a11..157e87b 100644 --- a/quine.asm +++ b/quine.asm @@ -471,10 +471,9 @@ end macro ; Take a 64-bit source register, store its value into the address pointed to ; by a 64-bit target register. ; -; For rbp, the only modes available also have displacement; we use an 8-bit -; one and set it to zero. The other registers could be encoded without the -; displacement, but for simplicity's sake we do the same thing for all of -; them. +; For a target of rbp, the only modes available also have displacement; we +; disallow that. Use mov.disp8.qreg.qreg for that case, and set a displacement +; of 0. ; ; In understanding this, pay close attention to the Op/En column in the opcode ; table. The "MR" variant means the ModRM byte's reg field (the middle one) @@ -495,17 +494,19 @@ end macro ; is for whichever register is specified in the R/M field. Sometimes that's ; the source, and sometimes it's the target, depending on the opcode. macro mov.indirect.qreg.qreg target, source + match =rbp, target + assert 0 + end match qwordreg sreg, source qwordreg treg, target rex.w db 0x89 - modrm 1, sreg, treg + modrm 0, sreg, treg match =rsp, target ; R/M = rsp is the SIB case sib 0, 4, treg ; no scaling, no indexing, target as base end match - db 0 end macro @@ -1038,7 +1039,7 @@ end macro ; ; We need to treat a target of rsp specially because it's the SIB case per ; table 2-2. -macro mov.disp8.qreg.qreg target, offset, source +macro mov.disp8.qreg.qreg offset, target, source qwordreg sreg, source qwordreg treg, target rex.w @@ -1723,7 +1724,7 @@ end macro ;;; macro pushcontrol source lea.qreg.disp8.qreg rbp, -8, rbp - mov.indirect.qreg.qreg rbp, source + mov.disp8.qreg.qreg 0, rbp, source end macro macro popcontrol target @@ -7229,7 +7230,9 @@ defword addressing_indirect_reg64, 0 dq dup, rbp, ne, zbranch, 23*8 ; Check whether the R/M register is rsp; save the test result for later. dq dup, rsp, eq, lit, 4, unroll + ; (equality result, output point, reg/op value, reg/mem name) dq reg64, lit, 0, unroll3, modrm + ; (equality result, output point) ; If the R/M register was rsp, we need an SIB byte; otherwise, skip it. dq swap, zbranch, 8*8, lit, 0, lit, 4, rsp, reg64, sib dq exit |