diff options
author | Kartik Agaram <vc@akkartik.com> | 2019-05-04 14:39:45 -0700 |
---|---|---|
committer | Kartik Agaram <vc@akkartik.com> | 2019-05-04 14:55:44 -0700 |
commit | 37aa2bf3e8c3b22c6b87925148cf938d1c1cc185 (patch) | |
tree | b295b9bece049031c082a1fd1c46003c1dc8c41b /subx/074print-int-decimal.subx | |
parent | 85a3e39cd5b4d11bc38d2fc400015770e1994774 (diff) | |
download | mu-37aa2bf3e8c3b22c6b87925148cf938d1c1cc185.tar.gz |
5142
Hoist address computation out of the loop. I'm giving in to the temptation to optimize here, and violating my own rule of minimizing local variables by introducing 'curr'. My fig leaf is that the number of instructions inside the loop goes down, and duplicating inside the loop may be distracting to readers.
Diffstat (limited to 'subx/074print-int-decimal.subx')
-rw-r--r-- | subx/074print-int-decimal.subx | 32 |
1 files changed, 20 insertions, 12 deletions
diff --git a/subx/074print-int-decimal.subx b/subx/074print-int-decimal.subx index a3f9bf9e..7f9dadc5 100644 --- a/subx/074print-int-decimal.subx +++ b/subx/074print-int-decimal.subx @@ -25,11 +25,15 @@ print-int32-decimal: # out : (address stream), n : int32 # if (EAX == 0) break # if n < 0 # push '-' + # w = out->write + # curr = &out->data[out->write] # while true # pop into EAX # if (EAX == sentinel) break - # out->data[out->write] = AL - # ++out->write + # *curr = AL + # ++curr + # ++w + # out->write = w # (based on K&R itoa: https://en.wikibooks.org/wiki/C_Programming/stdlib.h/itoa) # (this pseudocode contains registers because operations like division # require specific registers in x86) @@ -47,7 +51,7 @@ print-int32-decimal: # out : (address stream), n : int32 # push sentinel 68/push 0/imm32/sentinel # EAX = abs(n) - 8b/copy 1/mod/*+disp8 5/rm32/EBP . . . 0/r32/EAX 0xc/disp8 . # EAX = *(EBP+12) + 8b/copy 1/mod/*+disp8 5/rm32/EBP . . . 0/r32/EAX 0xc/disp8 . # copy *(EBP+12) to EAX 3d/compare-EAX-with 0/imm32 7d/jump-if-greater-or-equal $print-int32-decimal:read-loop/disp8 f7 3/subop/negate 3/mod/direct 0/rm32/EAX . . . . . . # negate EAX @@ -70,22 +74,26 @@ $print-int32-decimal:read-break: $print-int32-decimal:write: # EDI = out 8b/copy 1/mod/*+disp8 5/rm32/EBP . . . 7/r32/EDI 8/disp8 . # copy *(EBP+8) to EDI + # w/EDX = out->write + 8b/copy 0/mod/indirect 7/rm32/EDI . . . 2/r32/EDX . . # copy *EDI to EDX + # curr/ECX = &out->data[out->write] + 8d/copy-address 1/mod/*+disp8 4/rm32/sib 7/base/EDI 2/index/EDX . 1/r32/ECX 0xc/disp8 . # copy EBX+EDX+12 to ECX $print-int32-decimal:write-loop: # pop into EAX 58/pop-to-EAX # if (EAX == sentinel) break 3d/compare-EAX-and 0/imm32/sentinel - 74/jump-if-equal $print-int32-decimal:end/disp8 - # out->data[out->write] = AL - # . ECX = out->write - 8b/copy 0/mod/indirect 7/rm32/EDI . . . 1/r32/ECX . . # copy *EDI to ECX - # . ECX = &out->data[out->write] - 8d/copy-address 1/mod/*+disp8 4/rm32/sib 7/base/EDI 1/index/ECX . 1/r32/ECX 0xc/disp8 . # copy EBX+ECX+12 to ECX - # . out->data[out->write] = AL + 74/jump-if-equal $print-int32-decimal:write-break/disp8 + # *curr = AL 88/copy-byte 0/mod/indirect 1/rm32/ECX . . . 0/r32/AL . . # copy AL to byte at *ECX - # out->write++ - ff 0/subop/increment 0/mod/indirect 7/rm32/EDI . . . . . . # increment *EDI + # ++curr + 41/increment-ECX + # ++w + 42/increment-EDX eb/jump $print-int32-decimal:write-loop/disp8 +$print-int32-decimal:write-break: + # out->write = w + 89/copy 0/mod/indirect 7/rm32/EDI . . . 2/r32/EDX . . # copy EDX to *EDI $print-int32-decimal:end: # . restore registers 5f/pop-to-EDI |