From 9309600c5a8a5a86ac5aeebdee7bf0656409fc26 Mon Sep 17 00:00:00 2001 From: Kartik Agaram Date: Thu, 14 Feb 2019 23:00:47 -0800 Subject: 4967 --- html/subx/examples/ex10.subx.html | 61 ++-- html/subx/examples/ex11.subx.html | 644 +++++++++++++++++++------------------- html/subx/examples/ex3.subx.html | 2 +- html/subx/examples/ex8.subx.html | 4 +- 4 files changed, 359 insertions(+), 352 deletions(-) (limited to 'html/subx/examples') diff --git a/html/subx/examples/ex10.subx.html b/html/subx/examples/ex10.subx.html index 49383f99..6d48a9c2 100644 --- a/html/subx/examples/ex10.subx.html +++ b/html/subx/examples/ex10.subx.html @@ -96,37 +96,36 @@ if ('onhashchange' in window) { 38 # initialize s1 (ECX) and s2 (EDX) 39 8b/copy 1/mod/*+disp8 4/rm32/sib 4/base/ESP 4/index/none . 1/r32/ECX 4/disp8 . # copy *(ESP+4) to ECX 40 8b/copy 1/mod/*+disp8 4/rm32/sib 4/base/ESP 4/index/none . 2/r32/EDX 8/disp8 . # copy *(ESP+8) to EDX -41 # while (true) -42 $argv-equal:loop: -43 # c1/EAX, c2/EBX = *s1, *s2 -44 b8/copy-to-EAX 0/imm32 -45 8a/copy 0/mod/indirect 1/rm32/ECX . . . 0/r32/EAX . . # copy byte at *ECX to lower byte of EAX -46 bb/copy-to-EBX 0/imm32 -47 8a/copy 0/mod/indirect 2/rm32/EDX . . . 3/r32/EBX . . # copy byte at *EDX to lower byte of EBX -48 # if (c1 == 0) break -49 3d/compare-EAX 0/imm32 -50 74/jump-if-equal $argv-equal:break/disp8 -51 # if (c1 != c2) return false -52 39/compare 3/mod/direct 0/rm32/EAX . . . 3/r32/EBX . . # compare EAX with EBX -53 75/jump-if-not-equal $argv-equal:false/disp8 -54 # ++s1, ++s2 -55 41/inc-ECX -56 42/inc-EDX -57 # end while -58 eb/jump $argv-equal:loop/disp8 -59 $argv-equal:break: -60 # if (c2 == 0) return true -61 81 7/subop/compare 3/mod/direct 3/rm32/EBX . . . . . 0/imm32 # compare EBX -62 75/jump-if-not-equal $argv-equal:false/disp8 -63 $argv-equal:success: -64 b8/copy-to-EAX 1/imm32 -65 c3/return -66 # return false -67 $argv-equal:false: -68 b8/copy-to-EAX 0/imm32 -69 c3/return -70 -71 # . . vim:nowrap:textwidth=0 +41 $argv-equal:loop: +42 # c1/EAX, c2/EBX = *s1, *s2 +43 b8/copy-to-EAX 0/imm32 +44 8a/copy-byte 0/mod/indirect 1/rm32/ECX . . . 0/r32/AL . . # copy byte at *ECX to AL +45 bb/copy-to-EBX 0/imm32 +46 8a/copy-byte 0/mod/indirect 2/rm32/EDX . . . 3/r32/BL . . # copy byte at *EDX to BL +47 # if (c1 == 0) break +48 3d/compare-EAX 0/imm32 +49 74/jump-if-equal $argv-equal:break/disp8 +50 # if (c1 != c2) return false +51 39/compare 3/mod/direct 0/rm32/EAX . . . 3/r32/EBX . . # compare EAX with EBX +52 75/jump-if-not-equal $argv-equal:false/disp8 +53 # ++s1, ++s2 +54 41/inc-ECX +55 42/inc-EDX +56 # end while +57 eb/jump $argv-equal:loop/disp8 +58 $argv-equal:break: +59 # if (c2 == 0) return true +60 81 7/subop/compare 3/mod/direct 3/rm32/EBX . . . . . 0/imm32 # compare EBX +61 75/jump-if-not-equal $argv-equal:false/disp8 +62 $argv-equal:success: +63 b8/copy-to-EAX 1/imm32 +64 c3/return +65 # return false +66 $argv-equal:false: +67 b8/copy-to-EAX 0/imm32 +68 c3/return +69 +70 # . . vim:nowrap:textwidth=0 diff --git a/html/subx/examples/ex11.subx.html b/html/subx/examples/ex11.subx.html index 54d5982c..2aa43cf3 100644 --- a/html/subx/examples/ex11.subx.html +++ b/html/subx/examples/ex11.subx.html @@ -21,6 +21,7 @@ a { color:inherit; } .SpecialChar { color: #d70000; } .subxFunction { color: #af5f00; text-decoration: underline; } .subxTest { color: #5f8700; } +.subxMinorFunction { color: #875f5f; } .Normal { color: #000000; background-color: #c6c6c6; padding-bottom: 1px; } .subxS2Comment { color: #8a8a8a; } .subxH1Comment { color: #005faf; text-decoration: underline; } @@ -89,326 +90,333 @@ if ('onhashchange' in window) { 28 29 # compare a null-terminated ascii string with a more idiomatic length-prefixed byte array 30 # reason for the name: the only place we should have null-terminated ascii strings is from commandline args - 31 kernel-string-equal: # s : null-terminated ascii string, benchmark : length-prefixed ascii string -> EAX : boolean - 32 # . prolog - 33 55/push-EBP - 34 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP - 35 # . save registers - 36 51/push-ECX - 37 52/push-EDX - 38 53/push-EBX - 39 56/push-ESI - 40 57/push-EDI - 41 - 42 # pseudocode: - 43 # initialize n = b->length - 44 # initialize s1 = s - 45 # initialize s2 = b->data - 46 # i = 0 - 47 # for (i = 0; i < n; ++n) - 48 # c1 = *s1 - 49 # c2 = *s2 - 50 # if c1 == 0 - 51 # return false - 52 # if c1 != c2 - 53 # return false - 54 # return *s1 == 0 - 55 # initialize s into EDI - 56 8b/copy 1/mod/*+disp8 5/rm32/EBP . . . 7/r32/EDI 8/disp8 . # copy *(EBP+8) to EDI - 57 # initialize benchmark length n into EDX - 58 8b/copy 1/mod/*+disp8 5/rm32/EBP . . . 2/r32/EDX 0xc/disp8 . # copy *(EBP+12) to EDX - 59 8b/copy 0/mod/indirect 2/rm32/EDX . . . 2/r32/EDX . . # copy *EDX to EDX - 60 # initialize benchmark data into ESI - 61 8b/copy 1/mod/*+disp8 5/rm32/EBP . . . 6/r32/ESI 0xc/disp8 . # copy *(EBP+12) to ESI - 62 81 0/subop/add 3/mod/direct 6/rm32/ESI . . . . . 4/imm32 # add to ESI - 63 # initialize loop counter i into ECX - 64 b9/copy-to-ECX 0/imm32/exit - 65 # while (i/ECX < n/EDX) - 66 $kernel-string-equal:loop: - 67 39/compare 3/mod/direct 1/rm32/ECX . . . 2/r32/EDX . . # compare ECX with EDX - 68 74/jump-if-equal $kernel-string-equal:break/disp8 - 69 # c1/EAX, c2/EBX = *s, *benchmark - 70 b8/copy-to-EAX 0/imm32 - 71 8a/copy 0/mod/indirect 7/rm32/EDI . . . 0/r32/EAX . . # copy byte at *EDI to lower byte of EAX - 72 bb/copy-to-EBX 0/imm32 - 73 8a/copy 0/mod/indirect 6/rm32/ESI . . . 3/r32/EBX . . # copy byte at *ESI to lower byte of EBX - 74 # if (c1 == 0) return false - 75 3d/compare-EAX 0/imm32 - 76 74/jump-if-equal $kernel-string-equal:false/disp8 - 77 # if (c1 != c2) return false - 78 39/compare 3/mod/direct 0/rm32/EAX . . . 3/r32/EBX . . # compare EAX with EBX - 79 75/jump-if-not-equal $kernel-string-equal:false/disp8 - 80 # ++s1, ++s2, ++i - 81 41/inc-ECX - 82 46/inc-ESI - 83 47/inc-EDI - 84 # end while - 85 eb/jump $kernel-string-equal:loop/disp8 - 86 $kernel-string-equal:break: - 87 # if (*s/EDI == 0) return true - 88 b8/copy-to-EAX 0/imm32 - 89 8a/copy 0/mod/indirect 7/rm32/EDI . . . 0/r32/EAX . . # copy byte at *EDI to lower byte of EAX - 90 81 7/subop/compare 3/mod/direct 0/rm32/EAX . . . . . 0/imm32 # compare EAX - 91 75/jump-if-not-equal $kernel-string-equal:false/disp8 - 92 b8/copy-to-EAX 1/imm32 - 93 $kernel-string-equal:true: - 94 eb/jump $kernel-string-equal:end/disp8 - 95 # return false - 96 $kernel-string-equal:false: - 97 b8/copy-to-EAX 0/imm32 - 98 - 99 $kernel-string-equal:end: -100 # . restore registers -101 5f/pop-to-EDI -102 5e/pop-to-ESI -103 5b/pop-to-EBX -104 5a/pop-to-EDX -105 59/pop-to-ECX -106 # end -107 89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . . # copy EBP to ESP -108 5d/pop-to-EBP -109 c3/return -110 -111 # - tests -112 -113 test-compare-null-kernel-string-with-empty-array: -114 # EAX = kernel-string-equal(Null-kernel-string, "") -115 # . . push args -116 68/push ""/imm32 -117 68/push Null-kernel-string/imm32 -118 # . . call -119 e8/call kernel-string-equal/disp32 -120 # . . discard args -121 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP -122 # check-ints-equal(EAX, 1, msg) -123 # . . push args -124 68/push "F - test-compare-null-kernel-string-with-empty-array"/imm32 -125 68/push 1/imm32/true -126 50/push-EAX -127 # . . call -128 e8/call check-ints-equal/disp32 -129 # . . discard args -130 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP -131 c3/return -132 -133 test-compare-null-kernel-string-with-non-empty-array: -134 # EAX = kernel-string-equal(Null-kernel-string, "Abc") -135 # . . push args -136 68/push "Abc"/imm32 -137 68/push Null-kernel-string/imm32 -138 # . . call -139 e8/call kernel-string-equal/disp32 -140 # . . discard args -141 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP -142 # check-ints-equal(EAX, 0, msg) -143 # . . push args -144 68/push "F - test-compare-null-kernel-string-with-non-empty-array"/imm32 -145 68/push 0/imm32/false -146 50/push-EAX -147 # . . call -148 e8/call check-ints-equal/disp32 -149 # . . discard args -150 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP -151 c3/return -152 -153 test-compare-kernel-string-with-equal-array: -154 # EAX = kernel-string-equal(Abc-kernel-string, "Abc") -155 # . . push args -156 68/push "Abc"/imm32 -157 68/push Abc-kernel-string/imm32 -158 # . . call -159 e8/call kernel-string-equal/disp32 -160 # . . discard args -161 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP -162 # check-ints-equal(EAX, 1, msg) -163 # . . push args -164 68/push "F - test-compare-kernel-string-with-equal-array"/imm32 -165 68/push 1/imm32/true -166 50/push-EAX -167 # . . call -168 e8/call check-ints-equal/disp32 -169 # . . discard args -170 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP -171 c3/return -172 -173 test-compare-kernel-string-with-inequal-array: -174 # EAX = kernel-string-equal(Abc-kernel-string, "Adc") -175 # . . push args -176 68/push "Adc"/imm32 -177 68/push Abc-kernel-string/imm32 -178 # . . call -179 e8/call kernel-string-equal/disp32 -180 # . . discard args -181 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP -182 # check-ints-equal(EAX, 0, msg) -183 # . . push args -184 68/push "F - test-compare-kernel-string-with-equal-array"/imm32 -185 68/push 0/imm32/false -186 50/push-EAX -187 # . . call -188 e8/call check-ints-equal/disp32 -189 # . . discard args -190 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP -191 c3/return -192 -193 test-compare-kernel-string-with-empty-array: -194 # EAX = kernel-string-equal(Abc-kernel-string, "") -195 # . . push args -196 68/push ""/imm32 -197 68/push Abc-kernel-string/imm32 -198 # . . call -199 e8/call kernel-string-equal/disp32 -200 # . . discard args -201 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP -202 # check-ints-equal(EAX, 0, msg) -203 # . . push args -204 68/push "F - test-compare-kernel-string-with-equal-array"/imm32 -205 68/push 0/imm32/false -206 50/push-EAX -207 # . . call -208 e8/call check-ints-equal/disp32 -209 # . . discard args -210 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP -211 c3/return -212 -213 test-compare-kernel-string-with-shorter-array: -214 # EAX = kernel-string-equal(Abc-kernel-string, "Ab") -215 # . . push args -216 68/push "Ab"/imm32 -217 68/push Abc-kernel-string/imm32 -218 # . . call -219 e8/call kernel-string-equal/disp32 -220 # . . discard args -221 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP -222 # check-ints-equal(EAX, 0, msg) -223 # . . push args -224 68/push "F - test-compare-kernel-string-with-shorter-array"/imm32 -225 68/push 0/imm32/false -226 50/push-EAX -227 # . . call -228 e8/call check-ints-equal/disp32 -229 # . . discard args -230 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP -231 c3/return -232 -233 test-compare-kernel-string-with-longer-array: -234 # EAX = kernel-string-equal(Abc-kernel-string, "Abcd") -235 # . . push args -236 68/push "Abcd"/imm32 -237 68/push Abc-kernel-string/imm32 -238 # . . call -239 e8/call kernel-string-equal/disp32 -240 # . . discard args -241 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP -242 # check-ints-equal(EAX, 0, msg) -243 # . . push args -244 68/push "F - test-compare-kernel-string-with-longer-array"/imm32 -245 68/push 0/imm32/false -246 50/push-EAX -247 # . . call -248 e8/call check-ints-equal/disp32 -249 # . . discard args -250 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP -251 c3/return -252 -253 # - helpers -254 -255 # print msg to stderr if a != b, otherwise print "." -256 check-ints-equal: # (a : int, b : int, msg : (address array byte)) -> boolean -257 # . prolog -258 55/push-EBP -259 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP -260 # . save registers -261 51/push-ECX -262 53/push-EBX -263 # load args into EAX, EBX and ECX -264 8b/copy 1/mod/*+disp8 5/rm32/EBP . . . 0/r32/EAX 8/disp8 . # copy *(EBP+8) to EAX -265 8b/copy 1/mod/*+disp8 5/rm32/EBP . . . 3/r32/EBX 0xc/disp8 . # copy *(EBP+12) to EBX -266 # if EAX == b/EBX print('.') and return -267 39/compare 3/mod/direct 0/rm32/EAX . . . 3/r32/EBX . . # compare EAX and EBX -268 75/jump-if-unequal $check-ints-equal:else/disp8 -269 # . write-stderr('.') -270 # . . push args -271 68/push "."/imm32 -272 # . . call -273 e8/call write-stderr/disp32 -274 # . . discard args -275 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP -276 # . return -277 eb/jump $check-ints-equal:end/disp8 -278 # otherwise print(msg) -279 $check-ints-equal:else: -280 # copy msg into ECX -281 8b/copy 1/mod/*+disp8 5/rm32/EBP . . . 1/r32/ECX 0x10/disp8 . # copy *(EBP+16) to ECX -282 # print(ECX) -283 # . . push args -284 51/push-ECX -285 # . . call -286 e8/call write-stderr/disp32 -287 # . . discard args -288 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP -289 # print newline -290 # . . push args -291 68/push Newline/imm32 -292 # . . call -293 e8/call write-stderr/disp32 -294 # . . discard args -295 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP -296 $check-ints-equal:end: -297 # . restore registers -298 5b/pop-to-EBX -299 59/pop-to-ECX -300 # end -301 89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . . # copy EBP to ESP -302 5d/pop-to-EBP -303 c3/return -304 -305 write-stderr: # s : (address array byte) -> <void> -306 # . prolog -307 55/push-EBP -308 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP -309 # . save registers -310 50/push-EAX -311 51/push-ECX -312 52/push-EDX -313 53/push-EBX -314 # syscall(write, 2/stderr, (data) s+4, (size) *s) -315 # . . fd = 2 (stderr) -316 bb/copy-to-EBX 2/imm32 -317 # . . x = s+4 -318 8b/copy 1/mod/*+disp8 5/rm32/EBP . . . 1/r32/ECX 8/disp8 . # copy *(EBP+8) to ECX -319 81 0/subop/add 3/mod/direct 1/rm32/ECX . . . . . 4/imm32 # add to ECX -320 # . . size = *s -321 8b/copy 1/mod/*+disp8 5/rm32/EBP . . . 2/r32/EDX 8/disp8 . # copy *(EBP+8) to EDX -322 8b/copy 0/mod/indirect 2/rm32/EDX . . . 2/r32/EDX . . # copy *EDX to EDX -323 # . . syscall -324 b8/copy-to-EAX 4/imm32/write -325 cd/syscall 0x80/imm8 -326 # . restore registers -327 5b/pop-to-EBX -328 5a/pop-to-EDX -329 59/pop-to-ECX -330 58/pop-to-EAX -331 # . end -332 89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . . # copy EBP to ESP -333 5d/pop-to-EBP -334 c3/return -335 -336 == data -337 -338 Newline: -339 # size -340 01 00 00 00 -341 # data -342 0a/newline + 31 kernel-string-equal?: # s : null-terminated ascii string, benchmark : length-prefixed ascii string -> EAX : boolean + 32 # pseudocode: + 33 # n = benchmark->length + 34 # s1 = s + 35 # s2 = benchmark->data + 36 # i = 0 + 37 # while (i < n) + 38 # c1 = *s1 + 39 # c2 = *s2 + 40 # if (c1 == 0) return false + 41 # if (c1 != c2) return false + 42 # ++s1, ++s2, ++i + 43 # return *s1 == 0 + 44 # + 45 # registers: + 46 # i: ECX + 47 # n: EDX + 48 # s1: EDI + 49 # s2: ESI + 50 # c1: EAX + 51 # c2: EBX + 52 # + 53 # . prolog + 54 55/push-EBP + 55 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP + 56 # . save registers + 57 51/push-ECX + 58 52/push-EDX + 59 53/push-EBX + 60 56/push-ESI + 61 57/push-EDI + 62 # s1/EDI = s + 63 8b/copy 1/mod/*+disp8 5/rm32/EBP . . . 7/r32/EDI 8/disp8 . # copy *(EBP+8) to EDI + 64 # n/EDX = benchmark->length + 65 8b/copy 1/mod/*+disp8 5/rm32/EBP . . . 2/r32/EDX 0xc/disp8 . # copy *(EBP+12) to EDX + 66 8b/copy 0/mod/indirect 2/rm32/EDX . . . 2/r32/EDX . . # copy *EDX to EDX + 67 # s2/ESI = benchmark->data + 68 8b/copy 1/mod/*+disp8 5/rm32/EBP . . . 6/r32/ESI 0xc/disp8 . # copy *(EBP+12) to ESI + 69 81 0/subop/add 3/mod/direct 6/rm32/ESI . . . . . 4/imm32 # add to ESI + 70 # i/ECX = c1/EAX = c2/EBX = 0 + 71 b9/copy-to-ECX 0/imm32/exit + 72 b8/copy-to-EAX 0/imm32 + 73 bb/copy-to-EBX 0/imm32 + 74 $kernel-string-equal?:loop: + 75 # if (i >= n) break + 76 39/compare 3/mod/direct 1/rm32/ECX . . . 2/r32/EDX . . # compare ECX with EDX + 77 7d/jump-if-greater-or-equal $kernel-string-equal?:break/disp8 + 78 # c1 = *s1 + 79 8a/copy-byte 0/mod/indirect 7/rm32/EDI . . . 0/r32/AL . . # copy byte at *EDI to AL + 80 # c2 = *s2 + 81 8a/copy-byte 0/mod/indirect 6/rm32/ESI . . . 3/r32/BL . . # copy byte at *ESI to BL + 82 # if (c1 == 0) return false + 83 3d/compare-EAX 0/imm32 + 84 74/jump-if-equal $kernel-string-equal?:false/disp8 + 85 # if (c1 != c2) return false + 86 39/compare 3/mod/direct 0/rm32/EAX . . . 3/r32/EBX . . # compare EAX with EBX + 87 75/jump-if-not-equal $kernel-string-equal?:false/disp8 + 88 # ++i + 89 41/inc-ECX + 90 # ++s1 + 91 47/inc-EDI + 92 # ++s2 + 93 46/inc-ESI + 94 eb/jump $kernel-string-equal?:loop/disp8 + 95 $kernel-string-equal?:break: + 96 # return *s1 == 0 + 97 8a/copy-byte 0/mod/indirect 7/rm32/EDI . . . 0/r32/AL . . # copy byte at *EDI to AL + 98 3d/compare-EAX 0/imm32 + 99 75/jump-if-not-equal $kernel-string-equal?:false/disp8 +100 $kernel-string-equal?:true: +101 b8/copy-to-EAX 1/imm32 +102 eb/jump $kernel-string-equal?:end/disp8 +103 $kernel-string-equal?:false: +104 b8/copy-to-EAX 0/imm32 +105 $kernel-string-equal?:end: +106 # . restore registers +107 5f/pop-to-EDI +108 5e/pop-to-ESI +109 5b/pop-to-EBX +110 5a/pop-to-EDX +111 59/pop-to-ECX +112 # . epilog +113 89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . . # copy EBP to ESP +114 5d/pop-to-EBP +115 c3/return +116 +117 # - tests +118 +119 test-compare-null-kernel-string-with-empty-array: +120 # EAX = kernel-string-equal?(Null-kernel-string, "") +121 # . . push args +122 68/push ""/imm32 +123 68/push Null-kernel-string/imm32 +124 # . . call +125 e8/call kernel-string-equal?/disp32 +126 # . . discard args +127 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP +128 # check-ints-equal(EAX, 1, msg) +129 # . . push args +130 68/push "F - test-compare-null-kernel-string-with-empty-array"/imm32 +131 68/push 1/imm32/true +132 50/push-EAX +133 # . . call +134 e8/call check-ints-equal/disp32 +135 # . . discard args +136 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP +137 c3/return +138 +139 test-compare-null-kernel-string-with-non-empty-array: +140 # EAX = kernel-string-equal?(Null-kernel-string, "Abc") +141 # . . push args +142 68/push "Abc"/imm32 +143 68/push Null-kernel-string/imm32 +144 # . . call +145 e8/call kernel-string-equal?/disp32 +146 # . . discard args +147 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP +148 # check-ints-equal(EAX, 0, msg) +149 # . . push args +150 68/push "F - test-compare-null-kernel-string-with-non-empty-array"/imm32 +151 68/push 0/imm32/false +152 50/push-EAX +153 # . . call +154 e8/call check-ints-equal/disp32 +155 # . . discard args +156 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP +157 c3/return +158 +159 test-compare-kernel-string-with-equal-array: +160 # EAX = kernel-string-equal?(_test-Abc-kernel-string, "Abc") +161 # . . push args +162 68/push "Abc"/imm32 +163 68/push _test-Abc-kernel-string/imm32 +164 # . . call +165 e8/call kernel-string-equal?/disp32 +166 # . . discard args +167 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP +168 # check-ints-equal(EAX, 1, msg) +169 # . . push args +170 68/push "F - test-compare-kernel-string-with-equal-array"/imm32 +171 68/push 1/imm32/true +172 50/push-EAX +173 # . . call +174 e8/call check-ints-equal/disp32 +175 # . . discard args +176 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP +177 c3/return +178 +179 test-compare-kernel-string-with-inequal-array: +180 # EAX = kernel-string-equal?(_test-Abc-kernel-string, "Adc") +181 # . . push args +182 68/push "Adc"/imm32 +183 68/push _test-Abc-kernel-string/imm32 +184 # . . call +185 e8/call kernel-string-equal?/disp32 +186 # . . discard args +187 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP +188 # check-ints-equal(EAX, 0, msg) +189 # . . push args +190 68/push "F - test-compare-kernel-string-with-equal-array"/imm32 +191 68/push 0/imm32/false +192 50/push-EAX +193 # . . call +194 e8/call check-ints-equal/disp32 +195 # . . discard args +196 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP +197 c3/return +198 +199 test-compare-kernel-string-with-empty-array: +200 # EAX = kernel-string-equal?(_test-Abc-kernel-string, "") +201 # . . push args +202 68/push ""/imm32 +203 68/push _test-Abc-kernel-string/imm32 +204 # . . call +205 e8/call kernel-string-equal?/disp32 +206 # . . discard args +207 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP +208 # check-ints-equal(EAX, 0, msg) +209 # . . push args +210 68/push "F - test-compare-kernel-string-with-equal-array"/imm32 +211 68/push 0/imm32/false +212 50/push-EAX +213 # . . call +214 e8/call check-ints-equal/disp32 +215 # . . discard args +216 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP +217 c3/return +218 +219 test-compare-kernel-string-with-shorter-array: +220 # EAX = kernel-string-equal?(_test-Abc-kernel-string, "Ab") +221 # . . push args +222 68/push "Ab"/imm32 +223 68/push _test-Abc-kernel-string/imm32 +224 # . . call +225 e8/call kernel-string-equal?/disp32 +226 # . . discard args +227 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP +228 # check-ints-equal(EAX, 0, msg) +229 # . . push args +230 68/push "F - test-compare-kernel-string-with-shorter-array"/imm32 +231 68/push 0/imm32/false +232 50/push-EAX +233 # . . call +234 e8/call check-ints-equal/disp32 +235 # . . discard args +236 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP +237 c3/return +238 +239 test-compare-kernel-string-with-longer-array: +240 # EAX = kernel-string-equal?(_test-Abc-kernel-string, "Abcd") +241 # . . push args +242 68/push "Abcd"/imm32 +243 68/push _test-Abc-kernel-string/imm32 +244 # . . call +245 e8/call kernel-string-equal?/disp32 +246 # . . discard args +247 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP +248 # check-ints-equal(EAX, 0, msg) +249 # . . push args +250 68/push "F - test-compare-kernel-string-with-longer-array"/imm32 +251 68/push 0/imm32/false +252 50/push-EAX +253 # . . call +254 e8/call check-ints-equal/disp32 +255 # . . discard args +256 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP +257 c3/return +258 +259 # - helpers +260 +261 # print msg to stderr if a != b, otherwise print "." +262 check-ints-equal: # (a : int, b : int, msg : (address array byte)) -> boolean +263 # . prolog +264 55/push-EBP +265 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP +266 # . save registers +267 51/push-ECX +268 53/push-EBX +269 # load args into EAX, EBX and ECX +270 8b/copy 1/mod/*+disp8 5/rm32/EBP . . . 0/r32/EAX 8/disp8 . # copy *(EBP+8) to EAX +271 8b/copy 1/mod/*+disp8 5/rm32/EBP . . . 3/r32/EBX 0xc/disp8 . # copy *(EBP+12) to EBX +272 # if (EAX == b/EBX) print('.') and return +273 39/compare 3/mod/direct 0/rm32/EAX . . . 3/r32/EBX . . # compare EAX and EBX +274 75/jump-if-unequal $check-ints-equal:else/disp8 +275 # . write-stderr('.') +276 # . . push args +277 68/push "."/imm32 +278 # . . call +279 e8/call write-stderr/disp32 +280 # . . discard args +281 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP +282 # . return +283 eb/jump $check-ints-equal:end/disp8 +284 # otherwise print(msg) +285 $check-ints-equal:else: +286 # copy msg into ECX +287 8b/copy 1/mod/*+disp8 5/rm32/EBP . . . 1/r32/ECX 0x10/disp8 . # copy *(EBP+16) to ECX +288 # print(ECX) +289 # . . push args +290 51/push-ECX +291 # . . call +292 e8/call write-stderr/disp32 +293 # . . discard args +294 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP +295 # print newline +296 # . . push args +297 68/push Newline/imm32 +298 # . . call +299 e8/call write-stderr/disp32 +300 # . . discard args +301 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP +302 $check-ints-equal:end: +303 # . restore registers +304 5b/pop-to-EBX +305 59/pop-to-ECX +306 # end +307 89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . . # copy EBP to ESP +308 5d/pop-to-EBP +309 c3/return +310 +311 write-stderr: # s : (address array byte) -> <void> +312 # . prolog +313 55/push-EBP +314 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP +315 # . save registers +316 50/push-EAX +317 51/push-ECX +318 52/push-EDX +319 53/push-EBX +320 # syscall(write, 2/stderr, (data) s+4, (size) *s) +321 # . . fd = 2 (stderr) +322 bb/copy-to-EBX 2/imm32 +323 # . . x = s+4 +324 8b/copy 1/mod/*+disp8 5/rm32/EBP . . . 1/r32/ECX 8/disp8 . # copy *(EBP+8) to ECX +325 81 0/subop/add 3/mod/direct 1/rm32/ECX . . . . . 4/imm32 # add to ECX +326 # . . size = *s +327 8b/copy 1/mod/*+disp8 5/rm32/EBP . . . 2/r32/EDX 8/disp8 . # copy *(EBP+8) to EDX +328 8b/copy 0/mod/indirect 2/rm32/EDX . . . 2/r32/EDX . . # copy *EDX to EDX +329 # . . syscall +330 b8/copy-to-EAX 4/imm32/write +331 cd/syscall 0x80/imm8 +332 # . restore registers +333 5b/pop-to-EBX +334 5a/pop-to-EDX +335 59/pop-to-ECX +336 58/pop-to-EAX +337 # . end +338 89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . . # copy EBP to ESP +339 5d/pop-to-EBP +340 c3/return +341 +342 == data 343 -344 # for kernel-string-equal tests -345 Null-kernel-string: -346 00/null -347 Abc-kernel-string: -348 41/A 62/b 63/c 00/null +344 Newline: +345 # size +346 01 00 00 00 +347 # data +348 0a/newline 349 -350 # . . vim:nowrap:textwidth=0 +350 # for kernel-string-equal tests +351 Null-kernel-string: +352 00/null +353 +354 _test-Abc-kernel-string: +355 41/A 62/b 63/c 00/null +356 +357 # . . vim:nowrap:textwidth=0 diff --git a/html/subx/examples/ex3.subx.html b/html/subx/examples/ex3.subx.html index 655f9fbf..d7ace88f 100644 --- a/html/subx/examples/ex3.subx.html +++ b/html/subx/examples/ex3.subx.html @@ -75,7 +75,7 @@ if ('onhashchange' in window) { 18 b9/copy-to-ECX 1/imm32 19 20 $loop: -21 # while (counter <= 10) +21 # if (counter > 10) break 22 81 7/subop/compare 3/mod/direct 1/rm32/ECX . . . . . 0xa/imm32 # compare ECX 23 7f/jump-if-greater $exit/disp8 24 # result += counter diff --git a/html/subx/examples/ex8.subx.html b/html/subx/examples/ex8.subx.html index e0f26b54..03c23e36 100644 --- a/html/subx/examples/ex8.subx.html +++ b/html/subx/examples/ex8.subx.html @@ -99,8 +99,8 @@ if ('onhashchange' in window) { 41 b8/copy-to-EAX 0/imm32 42 $ascii-length-loop: 43 # var c/ECX = *s -44 8a/copy 0/mod/* 2/rm32/EDX . . . 1/r32/ECX . . # copy byte at *EDX to lower byte of ECX -45 # if c == '\0' break +44 8a/copy-byte 0/mod/* 2/rm32/EDX . . . 1/r32/CL . . # copy byte at *EDX to CL +45 # if (c == '\0') break 46 81 7/subop/compare 3/mod/direct 1/rm32/ECX . . . . . 0/imm32 # compare ECX 47 74/jump-if-equal $ascii-length-ret/disp8 48 # ++s -- cgit 1.4.1-2-gfad0