From d1c9392a5461e0d33e226375a8f7986a97d2d66b Mon Sep 17 00:00:00 2001 From: Kartik Agaram Date: Mon, 26 Nov 2018 01:19:47 -0800 Subject: 4782 --- html/subx/examples/ex11.subx.html | 650 +++++++++++++++++++------------------- 1 file changed, 326 insertions(+), 324 deletions(-) (limited to 'html/subx/examples/ex11.subx.html') diff --git a/html/subx/examples/ex11.subx.html b/html/subx/examples/ex11.subx.html index 7ac67838..0c4da4c4 100644 --- a/html/subx/examples/ex11.subx.html +++ b/html/subx/examples/ex11.subx.html @@ -16,7 +16,9 @@ a { color:#eeeeee; text-decoration: none; } a:hover { text-decoration: underline; } * { font-size: 12pt; font-size: 1em; } .LineNr { color: #444444; } +.Constant { color: #00a0a0; } .Delimiter { color: #800080; } +.Special { color: #c00000; } .Comment { color: #9090ff; } .Comment a { color:#0000ee; text-decoration:underline; } .SalientComment { color: #00ffff; } @@ -71,337 +73,337 @@ if ('onhashchange' in window) { 15 # would cause tests to not run, rather than to fail as we'd like.) 16 17 == code - 18 - 19 # instruction effective address operand displacement immediate - 20 # op subop mod rm32 base index scale r32 - 21 # 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 - 22 - 23 # main: - 24 e8/call run-tests/disp32 # 'run-tests' is a function created automatically by SubX. It calls all functions that start with 'test-'. - 25 # syscall(exit, EAX) - 26 89/copy 3/mod/direct 3/rm32/EBX . . . 0/r32/EAX . . # copy EAX to EBX - 27 b8/copy-to-EAX 1/imm32 - 28 cd/syscall 0x80/imm8 - 29 - 30 # compare a null-terminated ascii string with a more idiomatic length-prefixed byte array - 31 # reason for the name: the only place we should have null-terminated ascii strings is from commandline args - 32 kernel-string-equal: # s : null-terminated ascii string, benchmark : length-prefixed ascii string -> EAX : boolean - 33 # prolog - 34 55/push-EBP - 35 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP - 36 # save registers - 37 51/push-ECX - 38 52/push-EDX - 39 53/push-EBX - 40 56/push-ESI - 41 57/push-EDI - 42 - 43 # pseudocode: - 44 # initialize n = b.length - 45 # initialize s1 = s - 46 # initialize s2 = b.data - 47 # i = 0 - 48 # for (i = 0; i < n; ++n) - 49 # c1 = *s1 - 50 # c2 = *s2 - 51 # if c1 == 0 - 52 # return false - 53 # if c1 != c2 - 54 # return false - 55 # return *s1 == 0 - 56 # initialize s into EDI - 57 8b/copy 1/mod/*+disp8 4/rm32/sib 5/base/EBP 4/index/none . 7/r32/EDI 8/disp8 . # copy *(EBP+8) to EDI - 58 # initialize benchmark length n into EDX - 59 8b/copy 1/mod/*+disp8 4/rm32/sib 5/base/EBP 4/index/none . 2/r32/EDX 0xc/disp8 . # copy *(EBP+12) to EDX - 60 8b/copy 0/mod/indirect 2/rm32/EDX . . . 2/r32/EDX . . # copy *EDX to EDX - 61 # initialize benchmark data into ESI - 62 8b/copy 1/mod/*+disp8 4/rm32/sib 5/base/EBP 4/index/none . 6/r32/ESI 0xc/disp8 . # copy *(EBP+12) to ESI - 63 81 0/subop/add 3/mod/direct 6/rm32/ESI . . . . . 4/imm32 # add to ESI - 64 # initialize loop counter i into ECX - 65 b9/copy-to-ECX 0/imm32/exit - 66 # while (i/ECX < n/EDX) - 67 $kernel-string-equal:loop: - 68 39/compare 3/mod/direct 1/rm32/ECX . . . 2/r32/EDX . . # compare ECX with EDX - 69 74/jump-if-equal $kernel-string-equal:break/disp8 - 70 # c1/EAX, c2/EBX = *s, *benchmark - 71 b8/copy-to-EAX 0/imm32 - 72 8a/copy 0/mod/indirect 7/rm32/EDI . . . 0/r32/EAX . . # copy byte at *EDI to lower byte of EAX - 73 bb/copy-to-EBX 0/imm32 - 74 8a/copy 0/mod/indirect 6/rm32/ESI . . . 3/r32/EBX . . # copy byte at *ESI to lower byte of EBX - 75 # if (c1 == 0) return false - 76 3d/compare-EAX 0/imm32 - 77 74/jump-if-equal $kernel-string-equal:false/disp8 - 78 # if (c1 != c2) return false - 79 39/compare 3/mod/direct 0/rm32/EAX . . . 3/r32/EBX . . # compare EAX with EBX - 80 75/jump-if-not-equal $kernel-string-equal:false/disp8 - 81 # ++s1, ++s2, ++i - 82 41/inc-ECX - 83 46/inc-ESI - 84 47/inc-EDI - 85 # end while - 86 eb/jump $kernel-string-equal:loop/disp8 - 87 $kernel-string-equal:break: - 88 # if (*s/EDI == 0) return true - 89 b8/copy-to-EAX 0/imm32 - 90 8a/copy 0/mod/indirect 7/rm32/EDI . . . 0/r32/EAX . . # copy byte at *EDI to lower byte of EAX - 91 81 7/subop/compare 3/mod/direct 0/rm32/EAX . . . . . 0/imm32 # compare EAX - 92 75/jump-if-not-equal $kernel-string-equal:false/disp8 - 93 b8/copy-to-EAX 1/imm32 - 94 $kernel-string-equal:true: - 95 eb/jump $kernel-string-equal:end/disp8 - 96 # return false - 97 $kernel-string-equal:false: - 98 b8/copy-to-EAX 0/imm32 - 99 -100 $kernel-string-equal:end: -101 # restore registers -102 5f/pop-to-EDI -103 5e/pop-to-ESI -104 5b/pop-to-EBX -105 5a/pop-to-EDX -106 59/pop-to-ECX -107 # end -108 89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . . # copy EBP to ESP -109 5d/pop-to-EBP -110 c3/return -111 -112 ## tests -113 -114 test-compare-null-kernel-string-with-empty-array: -115 # EAX = kernel-string-equal(Null-kernel-string, "") -116 # push args -117 68/push ""/imm32 -118 68/push Null-kernel-string/imm32 -119 # call -120 e8/call kernel-string-equal/disp32 -121 # discard args -122 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP -123 # call check-ints-equal(EAX, 1, msg) -124 # push args -125 68/push "F - test-compare-null-kernel-string-with-empty-array"/imm32 -126 68/push 1/imm32/true -127 50/push-EAX -128 # call -129 e8/call check-ints-equal/disp32 -130 # discard args -131 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP -132 c3/return -133 -134 test-compare-null-kernel-string-with-non-empty-array: -135 # EAX = kernel-string-equal(Null-kernel-string, "Abc") -136 # push args -137 68/push "Abc"/imm32 -138 68/push Null-kernel-string/imm32 -139 # call -140 e8/call kernel-string-equal/disp32 -141 # discard args -142 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP -143 # call check-ints-equal(EAX, 0, msg) -144 # push args -145 68/push "F - test-compare-null-kernel-string-with-non-empty-array"/imm32 -146 68/push 0/imm32/false -147 50/push-EAX -148 # call -149 e8/call check-ints-equal/disp32 -150 # discard args -151 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP -152 c3/return -153 -154 test-compare-kernel-string-with-equal-array: -155 # EAX = kernel-string-equal(Abc-kernel-string, "Abc") -156 # push args -157 68/push "Abc"/imm32 -158 68/push Abc-kernel-string/imm32 -159 # call -160 e8/call kernel-string-equal/disp32 -161 # discard args -162 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP -163 # call check-ints-equal(EAX, 1, msg) -164 # push args -165 68/push "F - test-compare-kernel-string-with-equal-array"/imm32 -166 68/push 1/imm32/true -167 50/push-EAX -168 # call -169 e8/call check-ints-equal/disp32 -170 # discard args -171 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP -172 c3/return -173 -174 test-compare-kernel-string-with-inequal-array: -175 # EAX = kernel-string-equal(Abc-kernel-string, "Adc") -176 # push args -177 68/push "Adc"/imm32 -178 68/push Abc-kernel-string/imm32 -179 # call -180 e8/call kernel-string-equal/disp32 -181 # discard args -182 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP -183 # call check-ints-equal(EAX, 0, msg) -184 # push args -185 68/push "F - test-compare-kernel-string-with-equal-array"/imm32 -186 68/push 0/imm32/false -187 50/push-EAX -188 # call -189 e8/call check-ints-equal/disp32 -190 # discard args -191 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP -192 c3/return -193 -194 test-compare-kernel-string-with-empty-array: -195 # EAX = kernel-string-equal(Abc-kernel-string, "") -196 # push args -197 68/push ""/imm32 -198 68/push Abc-kernel-string/imm32 -199 # call -200 e8/call kernel-string-equal/disp32 -201 # discard args -202 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP -203 # call check-ints-equal(EAX, 0) -204 # push args -205 68/push "F - test-compare-kernel-string-with-equal-array"/imm32 -206 68/push 0/imm32/false -207 50/push-EAX -208 # call -209 e8/call check-ints-equal/disp32 -210 # discard args -211 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP -212 c3/return -213 -214 test-compare-kernel-string-with-shorter-array: -215 # EAX = kernel-string-equal(Abc-kernel-string, "Ab") -216 # push args -217 68/push "Ab"/imm32 -218 68/push Abc-kernel-string/imm32 -219 # call -220 e8/call kernel-string-equal/disp32 -221 # discard args -222 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP -223 # call check-ints-equal(EAX, 0) -224 # push args -225 68/push "F - test-compare-kernel-string-with-shorter-array"/imm32 -226 68/push 0/imm32/false -227 50/push-EAX -228 # call -229 e8/call check-ints-equal/disp32 -230 # discard args -231 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP -232 c3/return -233 -234 test-compare-kernel-string-with-longer-array: -235 # EAX = kernel-string-equal(Abc-kernel-string, "Abcd") -236 # push args -237 68/push "Abcd"/imm32 -238 68/push Abc-kernel-string/imm32 -239 # call -240 e8/call kernel-string-equal/disp32 -241 # discard args -242 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP -243 # call check-ints-equal(EAX, 0) -244 # push args -245 68/push "F - test-compare-kernel-string-with-longer-array"/imm32 -246 68/push 0/imm32/false -247 50/push-EAX -248 # call -249 e8/call check-ints-equal/disp32 -250 # discard args -251 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP -252 c3/return -253 -254 ## helpers -255 -256 # print msg to stderr if a != b, otherwise print "." -257 check-ints-equal: # (a : int, b : int, msg : (address array byte)) -> boolean -258 # prolog -259 55/push-EBP -260 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP -261 # save registers -262 51/push-ECX -263 53/push-EBX -264 # load args into EAX, EBX and ECX -265 8b/copy 1/mod/*+disp8 4/rm32/sib 5/base/EBP 4/index/none . 0/r32/EAX 0x8/disp8 . # copy *(EBP+8) to EAX -266 8b/copy 1/mod/*+disp8 4/rm32/sib 5/base/EBP 4/index/none . 3/r32/EBX 0xc/disp8 . # copy *(EBP+12) to EBX -267 # if EAX == b/EBX -268 39/compare 3/mod/direct 0/rm32/EAX . . . 3/r32/EBX . . # compare EAX and EBX -269 75/jump-if-unequal $check-ints-equal:else/disp8 -270 # print('.') -271 # push args -272 68/push "."/imm32 -273 # call -274 e8/call write-stderr/disp32 -275 # discard args -276 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP -277 # return -278 eb/jump $check-ints-equal:end/disp8 -279 # else: -280 $check-ints-equal:else: -281 # copy msg into ECX -282 8b/copy 1/mod/*+disp8 4/rm32/sib 5/base/EBP 4/index/none . 1/r32/ECX 0x10/disp8 . # copy *(EBP+16) to ECX -283 # print(ECX) -284 # push args -285 51/push-ECX -286 # call -287 e8/call write-stderr/disp32 -288 # discard args -289 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP -290 # print newline -291 # push args -292 68/push Newline/imm32 -293 # call -294 e8/call write-stderr/disp32 -295 # discard args -296 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP -297 $check-ints-equal:end: -298 # restore registers -299 5b/pop-to-EBX -300 59/pop-to-ECX -301 # end -302 89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . . # copy EBP to ESP -303 5d/pop-to-EBP -304 c3/return -305 -306 write-stderr: # s : (address array byte) -> <void> -307 # prolog -308 55/push-EBP -309 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP -310 # save registers -311 50/push-EAX -312 51/push-ECX -313 52/push-EDX -314 53/push-EBX -315 # syscall(write, 2/stderr, (data) s+4, (size) *s) -316 # fd = 2 (stderr) -317 bb/copy-to-EBX 2/imm32 -318 # x = s+4 -319 8b/copy 1/mod/*+disp8 4/rm32/sib 5/base/EBP 4/index/none . 1/r32/ECX 8/disp8 . # copy *(EBP+8) to ECX -320 81 0/subop/add 3/mod/direct 1/rm32/ECX . . . . . 4/imm32 # add to ECX -321 # size = *s -322 8b/copy 1/mod/*+disp8 4/rm32/sib 5/base/EBP 4/index/none . 2/r32/EDX 8/disp8 . # copy *(EBP+8) to EDX -323 8b/copy 0/mod/indirect 2/rm32/EDX . . . 2/r32/EDX . . # copy *EDX to EDX -324 # syscall -325 b8/copy-to-EAX 4/imm32/write -326 cd/syscall 0x80/imm8 -327 # restore registers -328 5b/pop-to-EBX -329 5a/pop-to-EDX -330 59/pop-to-ECX -331 58/pop-to-EAX -332 # end -333 89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . . # copy EBP to ESP -334 5d/pop-to-EBP -335 c3/return -336 -337 == data -338 Newline: + 18 # instruction effective address operand displacement immediate + 19 # op subop mod rm32 base index scale r32 + 20 # 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 + 21 + 22 # main: + 23 e8/call run-tests/disp32 # 'run-tests' is a function created automatically by SubX. It calls all functions that start with 'test-'. + 24 # syscall(exit, EAX) + 25 89/copy 3/mod/direct 3/rm32/EBX . . . 0/r32/EAX . . # copy EAX to EBX + 26 b8/copy-to-EAX 1/imm32 + 27 cd/syscall 0x80/imm8 + 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 4/rm32/sib 5/base/EBP 4/index/none . 7/r32/EDI 8/disp8 . # copy *(EBP+8) to EDI + 57 # initialize benchmark length n into EDX + 58 8b/copy 1/mod/*+disp8 4/rm32/sib 5/base/EBP 4/index/none . 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 4/rm32/sib 5/base/EBP 4/index/none . 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 # call 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 # call 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 # call 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 # call 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 # call check-ints-equal(EAX, 0) +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 # call check-ints-equal(EAX, 0) +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 # call check-ints-equal(EAX, 0) +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 4/rm32/sib 5/base/EBP 4/index/none . 0/r32/EAX 0x8/disp8 . # copy *(EBP+8) to EAX +265 8b/copy 1/mod/*+disp8 4/rm32/sib 5/base/EBP 4/index/none . 3/r32/EBX 0xc/disp8 . # copy *(EBP+12) to EBX +266 # if EAX == b/EBX +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 # print('.') +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 # else: +279 $check-ints-equal:else: +280 # copy msg into ECX +281 8b/copy 1/mod/*+disp8 4/rm32/sib 5/base/EBP 4/index/none . 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 4/rm32/sib 5/base/EBP 4/index/none . 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 4/rm32/sib 5/base/EBP 4/index/none . 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 343 344 # for kernel-string-equal tests -345 Null-kernel-string: +345 Null-kernel-string: 346 00/null -347 Abc-kernel-string: -348 41/A 62/b 63/c 00/null +347 Abc-kernel-string: +348 41/A 62/b 63/c 00/null 349 350 # vim:nowrap:textwidth=0 -- cgit 1.4.1-2-gfad0