From 52daf0722f7f4ad9d3f29e3cbbbaddde066f49f3 Mon Sep 17 00:00:00 2001 From: Kartik Agaram Date: Mon, 20 May 2019 01:44:06 -0700 Subject: 5211 Update syntax-highlighted renderings after a _long_ time. --- html/subx/074print-int-decimal.subx.html | 336 +++++++++++++++++-------------- 1 file changed, 183 insertions(+), 153 deletions(-) (limited to 'html/subx/074print-int-decimal.subx.html') diff --git a/html/subx/074print-int-decimal.subx.html b/html/subx/074print-int-decimal.subx.html index 9792c7d9..9eb8c9f8 100644 --- a/html/subx/074print-int-decimal.subx.html +++ b/html/subx/074print-int-decimal.subx.html @@ -68,109 +68,109 @@ if ('onhashchange' in window) { 6 # . 1-3 bytes 3 bits 2 bits 3 bits 3 bits 3 bits 2 bits 2 bits 0/1/2/4 bytes 0/1/2/4 bytes 7 8 #? Entry: # run a single test, while debugging - 9 #? e8/call test-print-int32-decimal/disp32 - 10 #? # syscall(exit, Num-test-failures) - 11 #? 8b/copy 0/mod/indirect 5/rm32/.disp32 . . 3/r32/EBX Num-test-failures/disp32 # copy *Num-test-failures to EBX - 12 #? b8/copy-to-EAX 1/imm32/exit - 13 #? cd/syscall 0x80/imm8 - 14 - 15 print-int32-decimal: # out : (address stream), n : int32 - 16 # works by generating characters from lowest to highest and pushing them - 17 # to the stack, before popping them one by one into the stream - 18 # - 19 # pseudocode: - 20 # copy ESP to EBX - 21 # EAX = |n| - 22 # while true - 23 # if (EAX == 0) break + 9 #? e8/call test-print-int32-decimal-negative/disp32 + 10 #? + 11 #? # syscall(exit, Num-test-failures) + 12 #? 8b/copy 0/mod/indirect 5/rm32/.disp32 . . 3/r32/EBX Num-test-failures/disp32 # copy *Num-test-failures to EBX + 13 #? b8/copy-to-EAX 1/imm32/exit + 14 #? cd/syscall 0x80/imm8 + 15 + 16 print-int32-decimal: # out : (address stream), n : int32 + 17 # works by generating characters from lowest to highest and pushing them + 18 # to the stack, before popping them one by one into the stream + 19 # + 20 # pseudocode: + 21 # push sentinel + 22 # EAX = abs(n) + 23 # while true 24 # sign-extend EAX into EDX 25 # EAX, EDX = EAX/10, EAX%10 - 26 # push EDX - 27 # if n < 0 - 28 # push '-' - '0' = -3 - 29 # max/ECX = &out->data[out->length] - 30 # w/EAX = out->write - 31 # curr/EDI = &out->data[out->write] - 32 # while true - 33 # if (ESP == EBX) break - 34 # if (curr >= max) abort - 35 # pop into EDX - 36 # EDX += '0' # convert decimal digit to ascii - 37 # *curr = DL - 38 # ++curr - 39 # ++w - 40 # out->write = w - 41 # - 42 # . prolog - 43 55/push-EBP - 44 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP - 45 # . save registers - 46 50/push-EAX - 47 51/push-ECX - 48 52/push-EDX - 49 53/push-EBX - 50 57/push-EDI - 51 # copy ESP to EBX - 52 89/copy 3/mod/direct 3/rm32/EBX . . . 4/r32/ESP . . # copy ESP to EBX - 53 # ten/ECX = 10 - 54 b9/copy-to-ECX 0xa/imm32 - 55 # EAX = |n| - 56 8b/copy 1/mod/*+disp8 5/rm32/EBP . . . 0/r32/EAX 0xc/disp8 . # copy *(EBP+12) to EAX - 57 3d/compare-EAX-with 0/imm32 - 58 7d/jump-if-greater-or-equal $print-int32-decimal:read-loop/disp8 - 59 $print-int32-decimal:negative: - 60 f7 3/subop/negate 3/mod/direct 0/rm32/EAX . . . . . . # negate EAX - 61 $print-int32-decimal:read-loop: - 62 # if (EAX == 0) break - 63 3d/compare-EAX-and 0/imm32 - 64 74/jump-if-equal $print-int32-decimal:read-break/disp8 - 65 # sign-extend - 66 99/sign-extend-EAX-into-EDX - 67 # EAX, EDX = divide-with-remainder EAX/ten, EAX%ten - 68 f7 7/subop/divide-by 3/mod/direct 1/rm32/ECX . . . . . . # divide EDX:EAX by ECX, storing quotient in EAX and remainder in EDX - 69 # push EDX - 70 52/push-EDX - 71 eb/jump $print-int32-decimal:read-loop/disp8 - 72 $print-int32-decimal:read-break: - 73 # if (n < 0) push('-') - 74 81 7/subop/compare 1/mod/*+disp8 5/rm32/EBP . . . . 0xc/disp8 0/imm32 # compare *(EBP+12) - 75 7d/jump-if-greater-or-equal $print-int32-decimal:write/disp8 - 76 $print-int32-decimal:push-negative: - 77 68/push -3/imm32/dash-minus-zero - 78 # fall through - 79 $print-int32-decimal:write: - 80 # EDI = out - 81 8b/copy 1/mod/*+disp8 5/rm32/EBP . . . 7/r32/EDI 8/disp8 . # copy *(EBP+8) to EDI - 82 # max/ECX = &out->data[out->length] - 83 8b/copy 1/mod/*+disp8 7/rm32/EDI . . . 1/r32/ECX 8/disp8 . # copy *(EDI+8) to ECX - 84 8d/copy-address 1/mod/*+disp8 4/rm32/sib 7/base/EDI 1/index/ECX . 1/r32/ECX 0xc/disp8 . # copy EDI+ECX+12 to ECX - 85 # w/EAX = out->write - 86 8b/copy 0/mod/indirect 7/rm32/EDI . . . 0/r32/EAX . . # copy *EDI to EAX - 87 # curr/EDI = &out->data[out->write] - 88 8d/copy-address 1/mod/*+disp8 4/rm32/sib 7/base/EDI 0/index/EAX . 7/r32/EDI 0xc/disp8 . # copy EDI+EAX+12 to EDI - 89 $print-int32-decimal:write-loop: - 90 # if (ESP == EBX) break - 91 39/compare 3/mod/direct 4/rm32/ESP . . . 3/r32/EBX . . # compare ESP and EBX - 92 74/jump-if-equal $print-int32-decimal:write-break/disp8 - 93 # if (curr >= max) abort - 94 39/compare 3/mod/direct 7/rm32/EDI . . . 1/r32/ECX . . # compare EDI and ECX - 95 7d/jump-if-greater-or-equal $print-int32-decimal:abort/disp8 - 96 # pop into EDX - 97 5a/pop-into-EDX - 98 # EDX += '0' - 99 81 0/subop/add 3/mod/direct 2/rm32/EDX . . . . . 0x30/imm32/zero # add to EDX -100 $print-int32-decimal:write-char: -101 # *curr = DL -102 88/copy-byte 0/mod/indirect 7/rm32/EDI . . . 2/r32/DL . . # copy DL to byte at *ECX -103 # ++curr -104 47/increment-EDI -105 # ++w -106 40/increment-EAX -107 eb/jump $print-int32-decimal:write-loop/disp8 -108 $print-int32-decimal:write-break: -109 # out->write = w -110 8b/copy 1/mod/*+disp8 5/rm32/EBP . . . 7/r32/EDI 8/disp8 . # copy *(EBP+8) to EDI -111 89/copy 0/mod/indirect 7/rm32/EDI . . . 0/r32/EAX . . # copy EAX to *EDI + 26 # EDX += '0' + 27 # push EDX + 28 # if (EAX == 0) break + 29 # if n < 0 + 30 # push '-' + 31 # w = out->write + 32 # curr = &out->data[out->write] + 33 # max = &out->data[out->length] + 34 # while true + 35 # pop into EAX + 36 # if (EAX == sentinel) break + 37 # if (curr >= max) abort + 38 # *curr = AL + 39 # ++curr + 40 # ++w + 41 # out->write = w + 42 # (based on K&R itoa: https://en.wikibooks.org/wiki/C_Programming/stdlib.h/itoa) + 43 # (this pseudocode contains registers because operations like division + 44 # require specific registers in x86) + 45 # + 46 # . prolog + 47 55/push-EBP + 48 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP + 49 # . save registers + 50 50/push-EAX + 51 51/push-ECX + 52 52/push-EDX + 53 53/push-EBX + 54 57/push-EDI + 55 # ten/ECX = 10 + 56 b9/copy-to-ECX 0xa/imm32 + 57 # push sentinel + 58 68/push 0/imm32/sentinel + 59 # EAX = abs(n) + 60 8b/copy 1/mod/*+disp8 5/rm32/EBP . . . 0/r32/EAX 0xc/disp8 . # copy *(EBP+12) to EAX + 61 3d/compare-EAX-with 0/imm32 + 62 7d/jump-if-greater-or-equal $print-int32-decimal:read-loop/disp8 + 63 $print-int32-decimal:negative: + 64 f7 3/subop/negate 3/mod/direct 0/rm32/EAX . . . . . . # negate EAX + 65 $print-int32-decimal:read-loop: + 66 # EAX, EDX = EAX / 10, EAX % 10 + 67 99/sign-extend-EAX-into-EDX + 68 f7 7/subop/idiv 3/mod/direct 1/rm32/ECX . . . . . . # divide EDX:EAX by ECX, storing quotient in EAX and remainder in EDX + 69 # EDX += '0' + 70 81 0/subop/add 3/mod/direct 2/rm32/EDX . . . . . 0x30/imm32 # add to EDX + 71 # push EDX + 72 52/push-EDX + 73 # if (EAX == 0) break + 74 3d/compare-EAX-and 0/imm32 + 75 7f/jump-if-greater $print-int32-decimal:read-loop/disp8 + 76 $print-int32-decimal:read-break: + 77 # if (n < 0) push('-') + 78 81 7/subop/compare 1/mod/*+disp8 5/rm32/EBP . . . . 0xc/disp8 0/imm32 # compare *(EBP+12) + 79 7d/jump-if-greater-or-equal $print-int32-decimal:write/disp8 + 80 $print-int32-decimal:push-negative: + 81 68/push 0x2d/imm32/- + 82 $print-int32-decimal:write: + 83 # EDI = out + 84 8b/copy 1/mod/*+disp8 5/rm32/EBP . . . 7/r32/EDI 8/disp8 . # copy *(EBP+8) to EDI + 85 # w/EDX = out->write + 86 8b/copy 0/mod/indirect 7/rm32/EDI . . . 2/r32/EDX . . # copy *EDI to EDX + 87 # curr/ECX = &out->data[out->write] + 88 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 + 89 # max/EBX = &out->data[out->length] + 90 8b/copy 1/mod/*+disp8 7/rm32/EDI . . . 3/r32/EBX 8/disp8 . # copy *(EDI+8) to EBX + 91 8d/copy-address 1/mod/*+disp8 4/rm32/sib 7/base/EDI 3/index/EBX . 3/r32/EBX 0xc/disp8 . # copy EDI+EBX+12 to EBX + 92 $print-int32-decimal:write-loop: + 93 # pop into EAX + 94 58/pop-to-EAX + 95 # if (EAX == sentinel) break + 96 3d/compare-EAX-and 0/imm32/sentinel + 97 74/jump-if-equal $print-int32-decimal:write-break/disp8 + 98 # if (curr >= max) abort + 99 39/compare 3/mod/direct 1/rm32/ECX . . . 3/r32/EBX . . # compare ECX with EBX +100 7d/jump-if-greater-or-equal $print-int32-decimal:abort/disp8 +101 $print-int32-decimal:write-char: +102 # *curr = AL +103 88/copy-byte 0/mod/indirect 1/rm32/ECX . . . 0/r32/AL . . # copy AL to byte at *ECX +104 # ++curr +105 41/increment-ECX +106 # ++w +107 42/increment-EDX +108 eb/jump $print-int32-decimal:write-loop/disp8 +109 $print-int32-decimal:write-break: +110 # out->write = w +111 89/copy 0/mod/indirect 7/rm32/EDI . . . 2/r32/EDX . . # copy EDX to *EDI 112 $print-int32-decimal:end: 113 # . restore registers 114 5f/pop-to-EDI @@ -213,7 +213,7 @@ if ('onhashchange' in window) { 151 68/push 9/imm32 152 68/push _test-stream/imm32 153 # . . call -154 e8/call print-int32-decimal/disp32 +154 e8/call print-int32-decimal/disp32 155 # . . discard args 156 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP 157 # check-stream-equal(_test-stream, "9", msg) @@ -222,14 +222,14 @@ if ('onhashchange' in window) { 160 68/push "9"/imm32 161 68/push _test-stream/imm32 162 # . . call -163 e8/call check-stream-equal/disp32 +163 e8/call check-stream-equal/disp32 164 # . . discard args 165 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP 166 # . end 167 c3/return 168 -169 test-print-int32-decimal-multiple-digits: -170 # - check that a multi-digit number converts correctly +169 test-print-int32-decimal-zero: +170 # - check that 0 converts correctly 171 # setup 172 # . clear-stream(_test-stream) 173 # . . push args @@ -238,28 +238,28 @@ if ('onhashchange' in window) { 176 e8/call clear-stream/disp32 177 # . . discard args 178 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP -179 # print-int32-decimal(_test-stream, 10) +179 # print-int32-decimal(_test-stream, 0) 180 # . . push args -181 68/push 0xa/imm32 +181 68/push 0/imm32 182 68/push _test-stream/imm32 183 # . . call -184 e8/call print-int32-decimal/disp32 +184 e8/call print-int32-decimal/disp32 185 # . . discard args 186 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP -187 # check-stream-equal(_test-stream, "10", msg) +187 # check-stream-equal(_test-stream, "0", msg) 188 # . . push args -189 68/push "F - test-print-int32-decimal-multiple-digits"/imm32 -190 68/push "10"/imm32 +189 68/push "F - test-print-int32-decimal-zero"/imm32 +190 68/push "0"/imm32 191 68/push _test-stream/imm32 192 # . . call -193 e8/call check-stream-equal/disp32 +193 e8/call check-stream-equal/disp32 194 # . . discard args 195 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP 196 # . end 197 c3/return 198 -199 test-print-int32-decimal-negative: -200 # - check that a negative single-digit number converts correctly +199 test-print-int32-decimal-multiple-digits: +200 # - check that a multi-digit number converts correctly 201 # setup 202 # . clear-stream(_test-stream) 203 # . . push args @@ -268,58 +268,88 @@ if ('onhashchange' in window) { 206 e8/call clear-stream/disp32 207 # . . discard args 208 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP -209 # print-int32-decimal(_test-stream, -9) +209 # print-int32-decimal(_test-stream, 10) 210 # . . push args -211 68/push -9/imm32 +211 68/push 0xa/imm32 212 68/push _test-stream/imm32 213 # . . call -214 e8/call print-int32-decimal/disp32 +214 e8/call print-int32-decimal/disp32 215 # . . discard args 216 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP -217 +-- 26 lines: #? # dump _test-stream --------------------------------------------------------------------------------------------------------------------- -243 # check-stream-equal(_test-stream, "-9", msg) -244 # . . push args -245 68/push "F - test-print-int32-decimal-negative"/imm32 -246 68/push "-9"/imm32 -247 68/push _test-stream/imm32 -248 # . . call -249 e8/call check-stream-equal/disp32 -250 # . . discard args -251 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP -252 # . end -253 c3/return -254 -255 test-print-int32-decimal-negative-multiple-digits: -256 # - check that a multi-digit number converts correctly -257 # setup -258 # . clear-stream(_test-stream) -259 # . . push args -260 68/push _test-stream/imm32 -261 # . . call -262 e8/call clear-stream/disp32 -263 # . . discard args -264 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP -265 # print-int32-decimal(_test-stream, -10) -266 # . . push args -267 68/push -0xa/imm32 -268 68/push _test-stream/imm32 -269 # . . call -270 e8/call print-int32-decimal/disp32 -271 # . . discard args -272 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP -273 # check-stream-equal(_test-stream, "-10", msg) +217 # check-stream-equal(_test-stream, "10", msg) +218 # . . push args +219 68/push "F - test-print-int32-decimal-multiple-digits"/imm32 +220 68/push "10"/imm32 +221 68/push _test-stream/imm32 +222 # . . call +223 e8/call check-stream-equal/disp32 +224 # . . discard args +225 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP +226 # . end +227 c3/return +228 +229 test-print-int32-decimal-negative: +230 # - check that a negative single-digit number converts correctly +231 # setup +232 # . clear-stream(_test-stream) +233 # . . push args +234 68/push _test-stream/imm32 +235 # . . call +236 e8/call clear-stream/disp32 +237 # . . discard args +238 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP +239 # print-int32-decimal(_test-stream, -9) +240 # . . push args +241 68/push -9/imm32 +242 68/push _test-stream/imm32 +243 # . . call +244 e8/call print-int32-decimal/disp32 +245 # . . discard args +246 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP +247 +-- 26 lines: #? # dump _test-stream --------------------------------------------------------------------------------------------------------------------- +273 # check-stream-equal(_test-stream, "-9", msg) 274 # . . push args -275 68/push "F - test-print-int32-decimal-negative-multiple-digits"/imm32 -276 68/push "-10"/imm32 +275 68/push "F - test-print-int32-decimal-negative"/imm32 +276 68/push "-9"/imm32 277 68/push _test-stream/imm32 278 # . . call -279 e8/call check-stream-equal/disp32 +279 e8/call check-stream-equal/disp32 280 # . . discard args 281 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP 282 # . end 283 c3/return 284 -285 # . . vim:nowrap:textwidth=0 +285 test-print-int32-decimal-negative-multiple-digits: +286 # - check that a multi-digit number converts correctly +287 # setup +288 # . clear-stream(_test-stream) +289 # . . push args +290 68/push _test-stream/imm32 +291 # . . call +292 e8/call clear-stream/disp32 +293 # . . discard args +294 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP +295 # print-int32-decimal(_test-stream, -10) +296 # . . push args +297 68/push -0xa/imm32 +298 68/push _test-stream/imm32 +299 # . . call +300 e8/call print-int32-decimal/disp32 +301 # . . discard args +302 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP +303 # check-stream-equal(_test-stream, "-10", msg) +304 # . . push args +305 68/push "F - test-print-int32-decimal-negative-multiple-digits"/imm32 +306 68/push "-10"/imm32 +307 68/push _test-stream/imm32 +308 # . . call +309 e8/call check-stream-equal/disp32 +310 # . . discard args +311 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP +312 # . end +313 c3/return +314 +315 # . . vim:nowrap:textwidth=0 -- cgit 1.4.1-2-gfad0