From 0af2ea07b33ac7c810cfb8f5aa124092e626228b Mon Sep 17 00:00:00 2001 From: Kartik Agaram Date: Tue, 23 Apr 2019 20:51:58 -0700 Subject: 5119 --- html/subx/apps/pack.subx.html | 11664 ++++++++++++++++++++-------------------- 1 file changed, 5837 insertions(+), 5827 deletions(-) (limited to 'html/subx/apps/pack.subx.html') diff --git a/html/subx/apps/pack.subx.html b/html/subx/apps/pack.subx.html index be124ece..72fc28de 100644 --- a/html/subx/apps/pack.subx.html +++ b/html/subx/apps/pack.subx.html @@ -217,5977 +217,5987 @@ if ('onhashchange' in window) { 153 # if (line->write == 0) break 154 81 7/subop/compare 0/mod/indirect 1/rm32/ECX . . . . . 0/imm32 # compare *ECX 155 0f 84/jump-if-equal $convert:break/disp32 - 156 +-- 34 lines: #? # dump line ----------------------------------------------------------------------------------------------------------------------------- - 190 # next-word(line, word-slice) - 191 # . . push args - 192 52/push-EDX - 193 51/push-ECX - 194 # . . call - 195 e8/call next-word/disp32 - 196 # . . discard args - 197 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP - 198 $convert:check1: - 199 # if (slice-empty?(word-slice)) write-stream-data(out, line) - 200 # . EAX = slice-empty?(word-slice) - 201 # . . push args - 202 52/push-EDX - 203 # . . call - 204 e8/call slice-empty?/disp32 - 205 # . . discard args - 206 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP - 207 # . if (EAX != 0) write-stream-data(out, line) - 208 3d/compare-EAX-and 0/imm32 - 209 0f 85/jump-if-not-equal $convert:pass-through/disp32 - 210 $convert:check2: - 211 +-- 50 lines: #? # dump word-slice ----------------------------------------------------------------------------------------------------------------------- - 261 # if (slice-equal?(word-slice, "==")) - 262 # word-slice = next-word(line) - 263 # in-code? = slice-equal?(word-slice, "code") - 264 # write-stream-data(out, line) - 265 # . EAX = slice-equal?(word-slice, "==") - 266 # . . push args - 267 68/push "=="/imm32 - 268 52/push-EDX - 269 # . . call - 270 e8/call slice-equal?/disp32 - 271 # . . discard args - 272 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP - 273 # . if (EAX == 0) goto check3 - 274 3d/compare-EAX-and 0/imm32 - 275 0f 84/jump-if-equal $convert:check3/disp32 - 276 # . next-word(line, word-slice) - 277 # . . push args - 278 52/push-EDX - 279 51/push-ECX - 280 # . . call - 281 e8/call next-word/disp32 - 282 # . . discard args - 283 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP - 284 +-- 50 lines: #? # dump segment name --------------------------------------------------------------------------------------------------------------------- - 334 # . in-code? = slice-equal?(word-slice, "code") - 335 # . . push args - 336 68/push "code"/imm32 - 337 52/push-EDX - 338 # . . call - 339 e8/call slice-equal?/disp32 - 340 # . . discard args - 341 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP - 342 # . . in-code? = EAX - 343 89/copy 3/mod/direct 3/rm32/EBX . . . 0/r32/EAX . . # copy EAX to EBX - 344 # . goto pass-through - 345 eb/jump $convert:pass-through/disp8 - 346 $convert:check3: - 347 # else rewind-stream(line) - 348 # . rewind-stream(line) - 349 # . . push args - 350 51/push-ECX - 351 # . . call - 352 e8/call rewind-stream/disp32 - 353 # . . discard args - 354 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP - 355 # if (in-code? != 0) convert-instruction(line, out) - 356 81 7/subop/compare 3/mod/direct 3/rm32/EBX . . . . . 0/imm32 # compare EBX - 357 74/jump-if-equal $convert:data/disp8 - 358 $convert:code: - 359 # . convert-instruction(line, out) - 360 # . . push args - 361 ff 6/subop/push 1/mod/*+disp8 5/rm32/EBP . . . . 0xc/disp8 . # push *(EBP+12) - 362 51/push-ECX - 363 # . . call - 364 e8/call convert-instruction/disp32 - 365 # . . discard args - 366 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP - 367 # . loop - 368 e9/jump $convert:loop/disp32 - 369 $convert:data: - 370 # else convert-data(line, out) - 371 # . . push args - 372 ff 6/subop/push 1/mod/*+disp8 5/rm32/EBP . . . . 0xc/disp8 . # push *(EBP+12) - 373 51/push-ECX - 374 # . . call - 375 e8/call convert-data/disp32 - 376 # . . discard args - 377 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP - 378 # . loop - 379 e9/jump $convert:loop/disp32 - 380 $convert:pass-through: - 381 # write-stream-data(out, line) - 382 # . . push args - 383 51/push-ECX - 384 ff 6/subop/push 1/mod/*+disp8 5/rm32/EBP . . . . 0xc/disp8 . # push *(EBP+12) - 385 # . . call - 386 e8/call write-stream-data/disp32 - 387 # . . discard args - 388 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP - 389 # . loop - 390 e9/jump $convert:loop/disp32 - 391 $convert:break: - 392 # flush(out) - 393 # . . push args - 394 ff 6/subop/push 1/mod/*+disp8 5/rm32/EBP . . . . 0xc/disp8 . # push *(EBP+12) - 395 # . . call - 396 e8/call flush/disp32 - 397 # . . discard args - 398 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP - 399 $convert:end: - 400 # . reclaim locals - 401 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0x214/imm32 # add to ESP - 402 # . restore registers - 403 5b/pop-to-EBX - 404 5a/pop-to-EDX - 405 59/pop-to-ECX - 406 58/pop-to-EAX - 407 # . epilog - 408 89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . . # copy EBP to ESP - 409 5d/pop-to-EBP - 410 c3/return - 411 - 412 test-convert-passes-empty-lines-through: - 413 # if a line is empty, pass it along unchanged - 414 # . prolog - 415 55/push-EBP - 416 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP - 417 # setup - 418 # . clear-stream(_test-input-stream) - 419 # . . push args - 420 68/push _test-input-stream/imm32 - 421 # . . call - 422 e8/call clear-stream/disp32 - 423 # . . discard args - 424 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP - 425 # . clear-stream(_test-input-buffered-file+4) - 426 # . . push args - 427 b8/copy-to-EAX _test-input-buffered-file/imm32 - 428 05/add-to-EAX 4/imm32 - 429 50/push-EAX - 430 # . . call - 431 e8/call clear-stream/disp32 - 432 # . . discard args - 433 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP - 434 # . clear-stream(_test-output-stream) - 435 # . . push args - 436 68/push _test-output-stream/imm32 - 437 # . . call - 438 e8/call clear-stream/disp32 - 439 # . . discard args - 440 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP - 441 # . clear-stream(_test-output-buffered-file+4) - 442 # . . push args - 443 b8/copy-to-EAX _test-output-buffered-file/imm32 - 444 05/add-to-EAX 4/imm32 - 445 50/push-EAX - 446 # . . call - 447 e8/call clear-stream/disp32 - 448 # . . discard args - 449 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP - 450 # write nothing to input - 451 # convert(_test-input-buffered-file, _test-output-buffered-file) - 452 # . . push args - 453 68/push _test-output-buffered-file/imm32 - 454 68/push _test-input-buffered-file/imm32 - 455 # . . call - 456 e8/call convert/disp32 - 457 # . . discard args - 458 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP - 459 # check that the line just passed through - 460 # . flush(_test-output-buffered-file) - 461 # . . push args - 462 68/push _test-output-buffered-file/imm32 - 463 # . . call - 464 e8/call flush/disp32 - 465 # . . discard args - 466 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP - 467 # . check-stream-equal(_test-output-stream, "", msg) - 468 # . . push args - 469 68/push "F - test-convert-passes-empty-lines-through"/imm32 - 470 68/push ""/imm32 - 471 68/push _test-output-stream/imm32 - 472 # . . call - 473 e8/call check-stream-equal/disp32 - 474 # . . discard args - 475 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP - 476 # . epilog - 477 89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . . # copy EBP to ESP - 478 5d/pop-to-EBP - 479 c3/return - 480 - 481 test-convert-passes-lines-with-just-whitespace-through: - 482 # if a line is empty, pass it along unchanged - 483 # . prolog - 484 55/push-EBP - 485 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP - 486 # setup - 487 # . clear-stream(_test-input-stream) - 488 # . . push args - 489 68/push _test-input-stream/imm32 - 490 # . . call - 491 e8/call clear-stream/disp32 - 492 # . . discard args - 493 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP - 494 # . clear-stream(_test-input-buffered-file+4) - 495 # . . push args - 496 b8/copy-to-EAX _test-input-buffered-file/imm32 - 497 05/add-to-EAX 4/imm32 - 498 50/push-EAX - 499 # . . call - 500 e8/call clear-stream/disp32 - 501 # . . discard args - 502 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP - 503 # . clear-stream(_test-output-stream) - 504 # . . push args - 505 68/push _test-output-stream/imm32 - 506 # . . call - 507 e8/call clear-stream/disp32 - 508 # . . discard args - 509 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP - 510 # . clear-stream(_test-output-buffered-file+4) - 511 # . . push args - 512 b8/copy-to-EAX _test-output-buffered-file/imm32 - 513 05/add-to-EAX 4/imm32 - 514 50/push-EAX - 515 # . . call - 516 e8/call clear-stream/disp32 - 517 # . . discard args - 518 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP - 519 # initialize input - 520 # . write(_test-input-stream, " ") + 156 +-- 26 lines: #? # dump line ----------------------------------------------------------------------------------------------------------------------------- + 182 # next-word(line, word-slice) + 183 # . . push args + 184 52/push-EDX + 185 51/push-ECX + 186 # . . call + 187 e8/call next-word/disp32 + 188 # . . discard args + 189 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP + 190 $convert:check1: + 191 # if (slice-empty?(word-slice)) write-stream-data(out, line) + 192 # . EAX = slice-empty?(word-slice) + 193 # . . push args + 194 52/push-EDX + 195 # . . call + 196 e8/call slice-empty?/disp32 + 197 # . . discard args + 198 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP + 199 # . if (EAX != 0) write-stream-data(out, line) + 200 3d/compare-EAX-and 0/imm32 + 201 0f 85/jump-if-not-equal $convert:pass-through/disp32 + 202 $convert:check2: + 203 +-- 42 lines: #? # dump word-slice ----------------------------------------------------------------------------------------------------------------------- + 245 # if (slice-equal?(word-slice, "==")) + 246 # word-slice = next-word(line) + 247 # in-code? = slice-equal?(word-slice, "code") + 248 # write-stream-data(out, line) + 249 # . EAX = slice-equal?(word-slice, "==") + 250 # . . push args + 251 68/push "=="/imm32 + 252 52/push-EDX + 253 # . . call + 254 e8/call slice-equal?/disp32 + 255 # . . discard args + 256 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP + 257 # . if (EAX == 0) goto check3 + 258 3d/compare-EAX-and 0/imm32 + 259 0f 84/jump-if-equal $convert:check3/disp32 + 260 # . next-word(line, word-slice) + 261 # . . push args + 262 52/push-EDX + 263 51/push-ECX + 264 # . . call + 265 e8/call next-word/disp32 + 266 # . . discard args + 267 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP + 268 +-- 42 lines: #? # dump segment name --------------------------------------------------------------------------------------------------------------------- + 310 # . in-code? = slice-equal?(word-slice, "code") + 311 # . . push args + 312 68/push "code"/imm32 + 313 52/push-EDX + 314 # . . call + 315 e8/call slice-equal?/disp32 + 316 # . . discard args + 317 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP + 318 # . . in-code? = EAX + 319 89/copy 3/mod/direct 3/rm32/EBX . . . 0/r32/EAX . . # copy EAX to EBX + 320 # . goto pass-through + 321 eb/jump $convert:pass-through/disp8 + 322 $convert:check3: + 323 # else rewind-stream(line) + 324 # . rewind-stream(line) + 325 # . . push args + 326 51/push-ECX + 327 # . . call + 328 e8/call rewind-stream/disp32 + 329 # . . discard args + 330 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP + 331 # if (in-code? != 0) convert-instruction(line, out) + 332 81 7/subop/compare 3/mod/direct 3/rm32/EBX . . . . . 0/imm32 # compare EBX + 333 74/jump-if-equal $convert:data/disp8 + 334 $convert:code: + 335 # . convert-instruction(line, out) + 336 # . . push args + 337 ff 6/subop/push 1/mod/*+disp8 5/rm32/EBP . . . . 0xc/disp8 . # push *(EBP+12) + 338 51/push-ECX + 339 # . . call + 340 e8/call convert-instruction/disp32 + 341 # . . discard args + 342 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP + 343 # . loop + 344 e9/jump $convert:loop/disp32 + 345 $convert:data: + 346 # else convert-data(line, out) + 347 # . . push args + 348 ff 6/subop/push 1/mod/*+disp8 5/rm32/EBP . . . . 0xc/disp8 . # push *(EBP+12) + 349 51/push-ECX + 350 # . . call + 351 e8/call convert-data/disp32 + 352 # . . discard args + 353 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP + 354 # . loop + 355 e9/jump $convert:loop/disp32 + 356 $convert:pass-through: + 357 # write-stream-data(out, line) + 358 # . . push args + 359 51/push-ECX + 360 ff 6/subop/push 1/mod/*+disp8 5/rm32/EBP . . . . 0xc/disp8 . # push *(EBP+12) + 361 # . . call + 362 e8/call write-stream-data/disp32 + 363 # . . discard args + 364 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP + 365 # . loop + 366 e9/jump $convert:loop/disp32 + 367 $convert:break: + 368 # flush(out) + 369 # . . push args + 370 ff 6/subop/push 1/mod/*+disp8 5/rm32/EBP . . . . 0xc/disp8 . # push *(EBP+12) + 371 # . . call + 372 e8/call flush/disp32 + 373 # . . discard args + 374 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP + 375 $convert:end: + 376 # . reclaim locals + 377 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0x214/imm32 # add to ESP + 378 # . restore registers + 379 5b/pop-to-EBX + 380 5a/pop-to-EDX + 381 59/pop-to-ECX + 382 58/pop-to-EAX + 383 # . epilog + 384 89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . . # copy EBP to ESP + 385 5d/pop-to-EBP + 386 c3/return + 387 + 388 test-convert-passes-empty-lines-through: + 389 # if a line is empty, pass it along unchanged + 390 # . prolog + 391 55/push-EBP + 392 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP + 393 # setup + 394 # . clear-stream(_test-input-stream) + 395 # . . push args + 396 68/push _test-input-stream/imm32 + 397 # . . call + 398 e8/call clear-stream/disp32 + 399 # . . discard args + 400 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP + 401 # . clear-stream(_test-input-buffered-file+4) + 402 # . . push args + 403 b8/copy-to-EAX _test-input-buffered-file/imm32 + 404 05/add-to-EAX 4/imm32 + 405 50/push-EAX + 406 # . . call + 407 e8/call clear-stream/disp32 + 408 # . . discard args + 409 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP + 410 # . clear-stream(_test-output-stream) + 411 # . . push args + 412 68/push _test-output-stream/imm32 + 413 # . . call + 414 e8/call clear-stream/disp32 + 415 # . . discard args + 416 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP + 417 # . clear-stream(_test-output-buffered-file+4) + 418 # . . push args + 419 b8/copy-to-EAX _test-output-buffered-file/imm32 + 420 05/add-to-EAX 4/imm32 + 421 50/push-EAX + 422 # . . call + 423 e8/call clear-stream/disp32 + 424 # . . discard args + 425 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP + 426 # write nothing to input + 427 # convert(_test-input-buffered-file, _test-output-buffered-file) + 428 # . . push args + 429 68/push _test-output-buffered-file/imm32 + 430 68/push _test-input-buffered-file/imm32 + 431 # . . call + 432 e8/call convert/disp32 + 433 # . . discard args + 434 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP + 435 # check that the line just passed through + 436 # . flush(_test-output-buffered-file) + 437 # . . push args + 438 68/push _test-output-buffered-file/imm32 + 439 # . . call + 440 e8/call flush/disp32 + 441 # . . discard args + 442 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP + 443 # . check-stream-equal(_test-output-stream, "", msg) + 444 # . . push args + 445 68/push "F - test-convert-passes-empty-lines-through"/imm32 + 446 68/push ""/imm32 + 447 68/push _test-output-stream/imm32 + 448 # . . call + 449 e8/call check-stream-equal/disp32 + 450 # . . discard args + 451 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP + 452 # . epilog + 453 89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . . # copy EBP to ESP + 454 5d/pop-to-EBP + 455 c3/return + 456 + 457 test-convert-passes-lines-with-just-whitespace-through: + 458 # if a line is empty, pass it along unchanged + 459 # . prolog + 460 55/push-EBP + 461 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP + 462 # setup + 463 # . clear-stream(_test-input-stream) + 464 # . . push args + 465 68/push _test-input-stream/imm32 + 466 # . . call + 467 e8/call clear-stream/disp32 + 468 # . . discard args + 469 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP + 470 # . clear-stream(_test-input-buffered-file+4) + 471 # . . push args + 472 b8/copy-to-EAX _test-input-buffered-file/imm32 + 473 05/add-to-EAX 4/imm32 + 474 50/push-EAX + 475 # . . call + 476 e8/call clear-stream/disp32 + 477 # . . discard args + 478 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP + 479 # . clear-stream(_test-output-stream) + 480 # . . push args + 481 68/push _test-output-stream/imm32 + 482 # . . call + 483 e8/call clear-stream/disp32 + 484 # . . discard args + 485 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP + 486 # . clear-stream(_test-output-buffered-file+4) + 487 # . . push args + 488 b8/copy-to-EAX _test-output-buffered-file/imm32 + 489 05/add-to-EAX 4/imm32 + 490 50/push-EAX + 491 # . . call + 492 e8/call clear-stream/disp32 + 493 # . . discard args + 494 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP + 495 # initialize input + 496 # . write(_test-input-stream, " ") + 497 # . . push args + 498 68/push " "/imm32 + 499 68/push _test-input-stream/imm32 + 500 # . . call + 501 e8/call write/disp32 + 502 # . . discard args + 503 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP + 504 # convert(_test-input-buffered-file, _test-output-buffered-file) + 505 # . . push args + 506 68/push _test-output-buffered-file/imm32 + 507 68/push _test-input-buffered-file/imm32 + 508 # . . call + 509 e8/call convert/disp32 + 510 # . . discard args + 511 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP + 512 # check that the line just passed through + 513 # . flush(_test-output-buffered-file) + 514 # . . push args + 515 68/push _test-output-buffered-file/imm32 + 516 # . . call + 517 e8/call flush/disp32 + 518 # . . discard args + 519 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP + 520 # . check-next-stream-line-equal(_test-output-stream, " ", msg) 521 # . . push args - 522 68/push " "/imm32 - 523 68/push _test-input-stream/imm32 - 524 # . . call - 525 e8/call write/disp32 - 526 # . . discard args - 527 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP - 528 # convert(_test-input-buffered-file, _test-output-buffered-file) - 529 # . . push args - 530 68/push _test-output-buffered-file/imm32 - 531 68/push _test-input-buffered-file/imm32 - 532 # . . call - 533 e8/call convert/disp32 - 534 # . . discard args - 535 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP - 536 # check that the line just passed through - 537 # . flush(_test-output-buffered-file) - 538 # . . push args - 539 68/push _test-output-buffered-file/imm32 - 540 # . . call - 541 e8/call flush/disp32 - 542 # . . discard args - 543 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP - 544 # . check-next-stream-line-equal(_test-output-stream, " ", msg) - 545 # . . push args - 546 68/push "F - test-convert-passes-with-just-whitespace-through"/imm32 - 547 68/push " "/imm32 - 548 68/push _test-output-stream/imm32 - 549 # . . call - 550 e8/call check-next-stream-line-equal/disp32 - 551 # . . discard args - 552 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP - 553 # . epilog - 554 89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . . # copy EBP to ESP - 555 5d/pop-to-EBP - 556 c3/return - 557 - 558 test-convert-passes-segment-headers-through: - 559 # if a line starts with '==', pass it along unchanged - 560 # . prolog - 561 55/push-EBP - 562 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP - 563 # setup - 564 # . clear-stream(_test-input-stream) - 565 # . . push args - 566 68/push _test-input-stream/imm32 - 567 # . . call - 568 e8/call clear-stream/disp32 - 569 # . . discard args - 570 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP - 571 # . clear-stream(_test-input-buffered-file+4) - 572 # . . push args - 573 b8/copy-to-EAX _test-input-buffered-file/imm32 - 574 05/add-to-EAX 4/imm32 - 575 50/push-EAX - 576 # . . call - 577 e8/call clear-stream/disp32 - 578 # . . discard args - 579 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP - 580 # . clear-stream(_test-output-stream) - 581 # . . push args - 582 68/push _test-output-stream/imm32 - 583 # . . call - 584 e8/call clear-stream/disp32 - 585 # . . discard args - 586 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP - 587 # . clear-stream(_test-output-buffered-file+4) - 588 # . . push args - 589 b8/copy-to-EAX _test-output-buffered-file/imm32 - 590 05/add-to-EAX 4/imm32 - 591 50/push-EAX - 592 # . . call - 593 e8/call clear-stream/disp32 - 594 # . . discard args - 595 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP - 596 # initialize input - 597 # . write(_test-input-stream, "== abcd") + 522 68/push "F - test-convert-passes-with-just-whitespace-through"/imm32 + 523 68/push " "/imm32 + 524 68/push _test-output-stream/imm32 + 525 # . . call + 526 e8/call check-next-stream-line-equal/disp32 + 527 # . . discard args + 528 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP + 529 # . epilog + 530 89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . . # copy EBP to ESP + 531 5d/pop-to-EBP + 532 c3/return + 533 + 534 test-convert-passes-segment-headers-through: + 535 # if a line starts with '==', pass it along unchanged + 536 # . prolog + 537 55/push-EBP + 538 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP + 539 # setup + 540 # . clear-stream(_test-input-stream) + 541 # . . push args + 542 68/push _test-input-stream/imm32 + 543 # . . call + 544 e8/call clear-stream/disp32 + 545 # . . discard args + 546 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP + 547 # . clear-stream(_test-input-buffered-file+4) + 548 # . . push args + 549 b8/copy-to-EAX _test-input-buffered-file/imm32 + 550 05/add-to-EAX 4/imm32 + 551 50/push-EAX + 552 # . . call + 553 e8/call clear-stream/disp32 + 554 # . . discard args + 555 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP + 556 # . clear-stream(_test-output-stream) + 557 # . . push args + 558 68/push _test-output-stream/imm32 + 559 # . . call + 560 e8/call clear-stream/disp32 + 561 # . . discard args + 562 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP + 563 # . clear-stream(_test-output-buffered-file+4) + 564 # . . push args + 565 b8/copy-to-EAX _test-output-buffered-file/imm32 + 566 05/add-to-EAX 4/imm32 + 567 50/push-EAX + 568 # . . call + 569 e8/call clear-stream/disp32 + 570 # . . discard args + 571 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP + 572 # initialize input + 573 # . write(_test-input-stream, "== abcd") + 574 # . . push args + 575 68/push "== abcd"/imm32 + 576 68/push _test-input-stream/imm32 + 577 # . . call + 578 e8/call write/disp32 + 579 # . . discard args + 580 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP + 581 # convert(_test-input-buffered-file, _test-output-buffered-file) + 582 # . . push args + 583 68/push _test-output-buffered-file/imm32 + 584 68/push _test-input-buffered-file/imm32 + 585 # . . call + 586 e8/call convert/disp32 + 587 # . . discard args + 588 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP + 589 # check that the line just passed through + 590 # . flush(_test-output-buffered-file) + 591 # . . push args + 592 68/push _test-output-buffered-file/imm32 + 593 # . . call + 594 e8/call flush/disp32 + 595 # . . discard args + 596 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP + 597 # . check-stream-equal(_test-output-stream, "== abcd", msg) 598 # . . push args - 599 68/push "== abcd"/imm32 - 600 68/push _test-input-stream/imm32 - 601 # . . call - 602 e8/call write/disp32 - 603 # . . discard args - 604 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP - 605 # convert(_test-input-buffered-file, _test-output-buffered-file) - 606 # . . push args - 607 68/push _test-output-buffered-file/imm32 - 608 68/push _test-input-buffered-file/imm32 - 609 # . . call - 610 e8/call convert/disp32 - 611 # . . discard args - 612 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP - 613 # check that the line just passed through - 614 # . flush(_test-output-buffered-file) - 615 # . . push args - 616 68/push _test-output-buffered-file/imm32 - 617 # . . call - 618 e8/call flush/disp32 - 619 # . . discard args - 620 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP - 621 # . check-stream-equal(_test-output-stream, "== abcd", msg) - 622 # . . push args - 623 68/push "F - test-convert-passes-segment-headers-through"/imm32 - 624 68/push "== abcd"/imm32 - 625 68/push _test-output-stream/imm32 - 626 # . . call - 627 e8/call check-stream-equal/disp32 - 628 # . . discard args - 629 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP - 630 # . epilog - 631 89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . . # copy EBP to ESP - 632 5d/pop-to-EBP - 633 c3/return - 634 - 635 test-convert-in-data-segment: - 636 # correctly process lines in the data segment - 637 # . prolog - 638 55/push-EBP - 639 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP - 640 # setup - 641 # . clear-stream(_test-input-stream) - 642 # . . push args - 643 68/push _test-input-stream/imm32 - 644 # . . call - 645 e8/call clear-stream/disp32 - 646 # . . discard args - 647 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP - 648 # . clear-stream(_test-input-buffered-file+4) - 649 # . . push args - 650 b8/copy-to-EAX _test-input-buffered-file/imm32 - 651 05/add-to-EAX 4/imm32 - 652 50/push-EAX - 653 # . . call - 654 e8/call clear-stream/disp32 - 655 # . . discard args - 656 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP - 657 # . clear-stream(_test-output-stream) - 658 # . . push args - 659 68/push _test-output-stream/imm32 - 660 # . . call - 661 e8/call clear-stream/disp32 - 662 # . . discard args - 663 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP - 664 # . clear-stream(_test-output-buffered-file+4) - 665 # . . push args - 666 b8/copy-to-EAX _test-output-buffered-file/imm32 - 667 05/add-to-EAX 4/imm32 - 668 50/push-EAX - 669 # . . call - 670 e8/call clear-stream/disp32 - 671 # . . discard args - 672 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP - 673 # initialize input - 674 # == code - 675 # == data - 676 # 3 4/imm32 - 677 # . write(_test-input-stream, "== code") + 599 68/push "F - test-convert-passes-segment-headers-through"/imm32 + 600 68/push "== abcd"/imm32 + 601 68/push _test-output-stream/imm32 + 602 # . . call + 603 e8/call check-stream-equal/disp32 + 604 # . . discard args + 605 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP + 606 # . epilog + 607 89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . . # copy EBP to ESP + 608 5d/pop-to-EBP + 609 c3/return + 610 + 611 test-convert-in-data-segment: + 612 # correctly process lines in the data segment + 613 # . prolog + 614 55/push-EBP + 615 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP + 616 # setup + 617 # . clear-stream(_test-input-stream) + 618 # . . push args + 619 68/push _test-input-stream/imm32 + 620 # . . call + 621 e8/call clear-stream/disp32 + 622 # . . discard args + 623 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP + 624 # . clear-stream(_test-input-buffered-file+4) + 625 # . . push args + 626 b8/copy-to-EAX _test-input-buffered-file/imm32 + 627 05/add-to-EAX 4/imm32 + 628 50/push-EAX + 629 # . . call + 630 e8/call clear-stream/disp32 + 631 # . . discard args + 632 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP + 633 # . clear-stream(_test-output-stream) + 634 # . . push args + 635 68/push _test-output-stream/imm32 + 636 # . . call + 637 e8/call clear-stream/disp32 + 638 # . . discard args + 639 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP + 640 # . clear-stream(_test-output-buffered-file+4) + 641 # . . push args + 642 b8/copy-to-EAX _test-output-buffered-file/imm32 + 643 05/add-to-EAX 4/imm32 + 644 50/push-EAX + 645 # . . call + 646 e8/call clear-stream/disp32 + 647 # . . discard args + 648 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP + 649 # initialize input + 650 # == code + 651 # == data + 652 # 3 4/imm32 + 653 # . write(_test-input-stream, "== code") + 654 # . . push args + 655 68/push "== code\n"/imm32 + 656 68/push _test-input-stream/imm32 + 657 # . . call + 658 e8/call write/disp32 + 659 # . . discard args + 660 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP + 661 # . write(_test-input-stream, "== data\n") + 662 # . . push args + 663 68/push "== data\n"/imm32 + 664 68/push _test-input-stream/imm32 + 665 # . . call + 666 e8/call write/disp32 + 667 # . . discard args + 668 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP + 669 # . write(_test-input-stream, "3 4/imm32\n") + 670 # . . push args + 671 68/push "3 4/imm32\n"/imm32 + 672 68/push _test-input-stream/imm32 + 673 # . . call + 674 e8/call write/disp32 + 675 # . . discard args + 676 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP + 677 # convert(_test-input-buffered-file, _test-output-buffered-file) 678 # . . push args - 679 68/push "== code"/imm32 - 680 68/push _test-input-stream/imm32 + 679 68/push _test-output-buffered-file/imm32 + 680 68/push _test-input-buffered-file/imm32 681 # . . call - 682 e8/call write/disp32 + 682 e8/call convert/disp32 683 # . . discard args 684 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP - 685 # . write(_test-input-stream, "\n") - 686 # . . push args - 687 68/push Newline/imm32 - 688 68/push _test-input-stream/imm32 - 689 # . . call - 690 e8/call write/disp32 - 691 # . . discard args - 692 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP - 693 # . write(_test-input-stream, "== data") - 694 # . . push args - 695 68/push "== data"/imm32 - 696 68/push _test-input-stream/imm32 - 697 # . . call - 698 e8/call write/disp32 - 699 # . . discard args - 700 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP - 701 # . write(_test-input-stream, "\n") - 702 # . . push args - 703 68/push Newline/imm32 - 704 68/push _test-input-stream/imm32 - 705 # . . call - 706 e8/call write/disp32 - 707 # . . discard args - 708 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP - 709 # . write(_test-input-stream, "3 4/imm32") - 710 # . . push args - 711 68/push "3 4/imm32"/imm32 - 712 68/push _test-input-stream/imm32 - 713 # . . call - 714 e8/call write/disp32 - 715 # . . discard args - 716 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP - 717 # . write(_test-input-stream, "\n") - 718 # . . push args - 719 68/push Newline/imm32 - 720 68/push _test-input-stream/imm32 - 721 # . . call - 722 e8/call write/disp32 - 723 # . . discard args - 724 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP - 725 # convert(_test-input-buffered-file, _test-output-buffered-file) - 726 # . . push args - 727 68/push _test-output-buffered-file/imm32 - 728 68/push _test-input-buffered-file/imm32 - 729 # . . call - 730 e8/call convert/disp32 - 731 # . . discard args - 732 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP - 733 # check output - 734 +-- 34 lines: #? # debug print --------------------------------------------------------------------------------------------------------------------------- - 768 # . flush(_test-output-buffered-file) - 769 # . . push args - 770 68/push _test-output-buffered-file/imm32 - 771 # . . call - 772 e8/call flush/disp32 - 773 # . . discard args - 774 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP - 775 # . check-next-stream-line-equal(_test-output-stream, "== code", msg) - 776 # . . push args - 777 68/push "F - test-convert-in-data-segment/0"/imm32 - 778 68/push "== code"/imm32 - 779 68/push _test-output-stream/imm32 - 780 # . . call - 781 e8/call check-next-stream-line-equal/disp32 - 782 # . . discard args - 783 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP - 784 # . check-next-stream-line-equal(_test-output-stream, "== data", msg) - 785 # . . push args - 786 68/push "F - test-convert-in-data-segment/1"/imm32 - 787 68/push "== data"/imm32 - 788 68/push _test-output-stream/imm32 - 789 # . . call - 790 e8/call check-next-stream-line-equal/disp32 - 791 # . . discard args - 792 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP - 793 # . check-next-stream-line-equal(_test-output-stream, "03 04 00 00 00 ", msg) - 794 # . . push args - 795 68/push "F - test-convert-in-data-segment/2"/imm32 - 796 68/push "03 04 00 00 00 "/imm32 - 797 68/push _test-output-stream/imm32 - 798 # . . call - 799 e8/call check-next-stream-line-equal/disp32 - 800 # . . discard args - 801 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP - 802 # . epilog - 803 89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . . # copy EBP to ESP - 804 5d/pop-to-EBP - 805 c3/return - 806 - 807 test-convert-code-and-data-segments: - 808 # correctly process lines in both code and data segments - 809 # . prolog - 810 55/push-EBP - 811 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP - 812 # setup - 813 # . clear-stream(_test-input-stream) - 814 # . . push args - 815 68/push _test-input-stream/imm32 - 816 # . . call - 817 e8/call clear-stream/disp32 - 818 # . . discard args - 819 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP - 820 # . clear-stream(_test-input-buffered-file+4) - 821 # . . push args - 822 b8/copy-to-EAX _test-input-buffered-file/imm32 - 823 05/add-to-EAX 4/imm32 - 824 50/push-EAX - 825 # . . call - 826 e8/call clear-stream/disp32 - 827 # . . discard args - 828 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP - 829 # . clear-stream(_test-output-stream) - 830 # . . push args - 831 68/push _test-output-stream/imm32 - 832 # . . call - 833 e8/call clear-stream/disp32 - 834 # . . discard args - 835 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP - 836 # . clear-stream(_test-output-buffered-file+4) - 837 # . . push args - 838 b8/copy-to-EAX _test-output-buffered-file/imm32 - 839 05/add-to-EAX 4/imm32 - 840 50/push-EAX - 841 # . . call - 842 e8/call clear-stream/disp32 - 843 # . . discard args - 844 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP - 845 # initialize input - 846 # == code - 847 # e8/call 20/disp32 - 848 # 68/push 0x20/imm8 - 849 # == data - 850 # 3 4/imm32 - 851 # . write(_test-input-stream, "== code") - 852 # . . push args - 853 68/push "== code"/imm32 - 854 68/push _test-input-stream/imm32 - 855 # . . call - 856 e8/call write/disp32 - 857 # . . discard args - 858 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP - 859 # . write(_test-input-stream, "\n") - 860 # . . push args - 861 68/push Newline/imm32 - 862 68/push _test-input-stream/imm32 - 863 # . . call - 864 e8/call write/disp32 - 865 # . . discard args - 866 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP - 867 # . write(_test-input-stream, "e8/call 20/disp32") - 868 # . . push args - 869 68/push "e8/call 20/disp32"/imm32 - 870 68/push _test-input-stream/imm32 - 871 # . . call - 872 e8/call write/disp32 - 873 # . . discard args - 874 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP - 875 # . write(_test-input-stream, "\n") + 685 # check output + 686 +-- 26 lines: #? # debug print --------------------------------------------------------------------------------------------------------------------------- + 712 # . flush(_test-output-buffered-file) + 713 # . . push args + 714 68/push _test-output-buffered-file/imm32 + 715 # . . call + 716 e8/call flush/disp32 + 717 # . . discard args + 718 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP + 719 # . check-next-stream-line-equal(_test-output-stream, "== code", msg) + 720 # . . push args + 721 68/push "F - test-convert-in-data-segment/0"/imm32 + 722 68/push "== code"/imm32 + 723 68/push _test-output-stream/imm32 + 724 # . . call + 725 e8/call check-next-stream-line-equal/disp32 + 726 # . . discard args + 727 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP + 728 # . check-next-stream-line-equal(_test-output-stream, "== data", msg) + 729 # . . push args + 730 68/push "F - test-convert-in-data-segment/1"/imm32 + 731 68/push "== data"/imm32 + 732 68/push _test-output-stream/imm32 + 733 # . . call + 734 e8/call check-next-stream-line-equal/disp32 + 735 # . . discard args + 736 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP + 737 # . check-next-stream-line-equal(_test-output-stream, "03 04 00 00 00 ", msg) + 738 # . . push args + 739 68/push "F - test-convert-in-data-segment/2"/imm32 + 740 68/push "03 04 00 00 00 "/imm32 + 741 68/push _test-output-stream/imm32 + 742 # . . call + 743 e8/call check-next-stream-line-equal/disp32 + 744 # . . discard args + 745 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP + 746 # . epilog + 747 89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . . # copy EBP to ESP + 748 5d/pop-to-EBP + 749 c3/return + 750 + 751 test-convert-code-and-data-segments: + 752 # correctly process lines in both code and data segments + 753 # . prolog + 754 55/push-EBP + 755 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP + 756 # setup + 757 # . clear-stream(_test-input-stream) + 758 # . . push args + 759 68/push _test-input-stream/imm32 + 760 # . . call + 761 e8/call clear-stream/disp32 + 762 # . . discard args + 763 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP + 764 # . clear-stream(_test-input-buffered-file+4) + 765 # . . push args + 766 b8/copy-to-EAX _test-input-buffered-file/imm32 + 767 05/add-to-EAX 4/imm32 + 768 50/push-EAX + 769 # . . call + 770 e8/call clear-stream/disp32 + 771 # . . discard args + 772 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP + 773 # . clear-stream(_test-output-stream) + 774 # . . push args + 775 68/push _test-output-stream/imm32 + 776 # . . call + 777 e8/call clear-stream/disp32 + 778 # . . discard args + 779 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP + 780 # . clear-stream(_test-output-buffered-file+4) + 781 # . . push args + 782 b8/copy-to-EAX _test-output-buffered-file/imm32 + 783 05/add-to-EAX 4/imm32 + 784 50/push-EAX + 785 # . . call + 786 e8/call clear-stream/disp32 + 787 # . . discard args + 788 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP + 789 # initialize input + 790 # == code + 791 # e8/call 20/disp32 + 792 # 68/push 0x20/imm8 + 793 # == data + 794 # 3 4/imm32 + 795 # . write(_test-input-stream, "== code\n") + 796 # . . push args + 797 68/push "== code\n"/imm32 + 798 68/push _test-input-stream/imm32 + 799 # . . call + 800 e8/call write/disp32 + 801 # . . discard args + 802 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP + 803 # . write(_test-input-stream, "e8/call 20/disp32\n") + 804 # . . push args + 805 68/push "e8/call 20/disp32\n"/imm32 + 806 68/push _test-input-stream/imm32 + 807 # . . call + 808 e8/call write/disp32 + 809 # . . discard args + 810 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP + 811 # . write(_test-input-stream, "68/push 0x20/imm8\n") + 812 # . . push args + 813 68/push "68/push 0x20/imm8\n"/imm32 + 814 68/push _test-input-stream/imm32 + 815 # . . call + 816 e8/call write/disp32 + 817 # . . discard args + 818 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP + 819 # . write(_test-input-stream, "== data\n") + 820 # . . push args + 821 68/push "== data\n"/imm32 + 822 68/push _test-input-stream/imm32 + 823 # . . call + 824 e8/call write/disp32 + 825 # . . discard args + 826 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP + 827 # . write(_test-input-stream, "3 4/imm32\n") + 828 # . . push args + 829 68/push "3 4/imm32\n"/imm32 + 830 68/push _test-input-stream/imm32 + 831 # . . call + 832 e8/call write/disp32 + 833 # . . discard args + 834 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP + 835 # convert(_test-input-buffered-file, _test-output-buffered-file) + 836 # . . push args + 837 68/push _test-output-buffered-file/imm32 + 838 68/push _test-input-buffered-file/imm32 + 839 # . . call + 840 e8/call convert/disp32 + 841 # . . discard args + 842 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP + 843 # check output + 844 # == code + 845 # e8 20 00 00 00 # e8/call 20/disp32 + 846 # 68 20 # 68/push 0x20/imm8 + 847 # == data + 848 # 03 04 00 00 00 + 849 +-- 26 lines: #? # debug print --------------------------------------------------------------------------------------------------------------------------- + 875 # . flush(_test-output-buffered-file) 876 # . . push args - 877 68/push Newline/imm32 - 878 68/push _test-input-stream/imm32 - 879 # . . call - 880 e8/call write/disp32 - 881 # . . discard args - 882 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP - 883 # . write(_test-input-stream, "68/push 0x20/imm8") - 884 # . . push args - 885 68/push "68/push 0x20/imm8"/imm32 - 886 68/push _test-input-stream/imm32 + 877 68/push _test-output-buffered-file/imm32 + 878 # . . call + 879 e8/call flush/disp32 + 880 # . . discard args + 881 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP + 882 # . check-next-stream-line-equal(_test-output-stream, "== code", msg) + 883 # . . push args + 884 68/push "F - test-convert-code-and-data-segments/0"/imm32 + 885 68/push "== code"/imm32 + 886 68/push _test-output-stream/imm32 887 # . . call - 888 e8/call write/disp32 + 888 e8/call check-next-stream-line-equal/disp32 889 # . . discard args - 890 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP - 891 # . write(_test-input-stream, "\n") + 890 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP + 891 # . check-next-stream-line-equal(_test-output-stream, "e8 20 00 00 00 # e8/call 20/disp32", msg) 892 # . . push args - 893 68/push Newline/imm32 - 894 68/push _test-input-stream/imm32 - 895 # . . call - 896 e8/call write/disp32 - 897 # . . discard args - 898 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP - 899 # . write(_test-input-stream, "== data") - 900 # . . push args - 901 68/push "== data"/imm32 - 902 68/push _test-input-stream/imm32 - 903 # . . call - 904 e8/call write/disp32 - 905 # . . discard args - 906 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP - 907 # . write(_test-input-stream, "\n") - 908 # . . push args - 909 68/push Newline/imm32 - 910 68/push _test-input-stream/imm32 - 911 # . . call - 912 e8/call write/disp32 - 913 # . . discard args - 914 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP - 915 # . write(_test-input-stream, "3 4/imm32") - 916 # . . push args - 917 68/push "3 4/imm32"/imm32 - 918 68/push _test-input-stream/imm32 - 919 # . . call - 920 e8/call write/disp32 - 921 # . . discard args - 922 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP - 923 # . write(_test-input-stream, "\n") - 924 # . . push args - 925 68/push Newline/imm32 - 926 68/push _test-input-stream/imm32 - 927 # . . call - 928 e8/call write/disp32 - 929 # . . discard args - 930 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP - 931 # convert(_test-input-buffered-file, _test-output-buffered-file) - 932 # . . push args - 933 68/push _test-output-buffered-file/imm32 - 934 68/push _test-input-buffered-file/imm32 - 935 # . . call - 936 e8/call convert/disp32 - 937 # . . discard args - 938 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP - 939 # check output - 940 # == code - 941 # e8 20 00 00 00 # e8/call 20/disp32 - 942 # 68 20 # 68/push 0x20/imm8 - 943 # == data - 944 # 03 04 00 00 00 - 945 +-- 34 lines: #? # debug print --------------------------------------------------------------------------------------------------------------------------- - 979 # . flush(_test-output-buffered-file) - 980 # . . push args - 981 68/push _test-output-buffered-file/imm32 - 982 # . . call - 983 e8/call flush/disp32 - 984 # . . discard args - 985 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP - 986 # . check-next-stream-line-equal(_test-output-stream, "== code", msg) - 987 # . . push args - 988 68/push "F - test-convert-code-and-data-segments/0"/imm32 - 989 68/push "== code"/imm32 - 990 68/push _test-output-stream/imm32 - 991 # . . call - 992 e8/call check-next-stream-line-equal/disp32 - 993 # . . discard args - 994 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP - 995 # . check-next-stream-line-equal(_test-output-stream, "e8 20 00 00 00 # e8/call 20/disp32", msg) - 996 # . . push args - 997 68/push "F - test-convert-code-and-data-segments/1"/imm32 - 998 68/push "e8 20 00 00 00 # e8/call 20/disp32"/imm32 - 999 68/push _test-output-stream/imm32 -1000 # . . call -1001 e8/call check-next-stream-line-equal/disp32 -1002 # . . discard args -1003 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP -1004 # . check-next-stream-line-equal(_test-output-stream, "68 20 # 68/push 0x20/imm8", msg) -1005 # . . push args -1006 68/push "F - test-convert-code-and-data-segments/2"/imm32 -1007 68/push "68 20 # 68/push 0x20/imm8"/imm32 -1008 68/push _test-output-stream/imm32 -1009 # . . call -1010 e8/call check-next-stream-line-equal/disp32 -1011 # . . discard args -1012 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP -1013 # . check-next-stream-line-equal(_test-output-stream, "== data", msg) -1014 # . . push args -1015 68/push "F - test-convert-code-and-data-segments/3"/imm32 -1016 68/push "== data"/imm32 -1017 68/push _test-output-stream/imm32 -1018 # . . call -1019 e8/call check-next-stream-line-equal/disp32 -1020 # . . discard args -1021 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP -1022 # . check-next-stream-line-equal(_test-output-stream, "03 04 00 00 00 ", msg) -1023 # . . push args -1024 68/push "F - test-convert-code-and-data-segments/4"/imm32 -1025 68/push "03 04 00 00 00 "/imm32 -1026 68/push _test-output-stream/imm32 -1027 # . . call -1028 e8/call check-next-stream-line-equal/disp32 -1029 # . . discard args -1030 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP -1031 # . epilog -1032 89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . . # copy EBP to ESP -1033 5d/pop-to-EBP -1034 c3/return -1035 -1036 convert-data: # line : (address stream byte), out : (address buffered-file) -> <void> -1037 # pseudocode: -1038 # var word-slice = {0, 0} -1039 # while true -1040 # word-slice = next-word(line) -1041 # if slice-empty?(word-slice) # end of file (maybe including trailing whitespace) -1042 # break # skip emitting some whitespace -1043 # if slice-starts-with?(word-slice, "#") # comment -1044 # write-slice(out, word-slice) -1045 # break -1046 # if slice-ends-with?(word-slice, ":") # label -1047 # write-stream-data(out, line) -1048 # break -1049 # if has-metadata?(word-slice, "imm32") -1050 # emit(out, word-slice, 4) -1051 # # disp32 is not permitted in data segments, and anything else is only a byte long -1052 # else -1053 # emit(out, word-slice, 1) -1054 # -1055 # . prolog -1056 55/push-EBP -1057 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP -1058 # . save registers -1059 50/push-EAX -1060 51/push-ECX -1061 52/push-EDX -1062 # var word-slice/ECX = {0, 0} -1063 68/push 0/imm32/end -1064 68/push 0/imm32/start -1065 89/copy 3/mod/direct 1/rm32/ECX . . . 4/r32/ESP . . # copy ESP to ECX -1066 +-- 34 lines: #? # dump line ----------------------------------------------------------------------------------------------------------------------------- -1100 $convert-data:loop: -1101 # next-word(line, word-slice) -1102 # . . push args -1103 51/push-ECX -1104 ff 6/subop/push 1/mod/*+disp8 5/rm32/EBP . . . . 8/disp8 . # push *(EBP+8) -1105 # . . call -1106 e8/call next-word/disp32 -1107 # . . discard args -1108 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP -1109 +-- 50 lines: #? # dump word-slice ----------------------------------------------------------------------------------------------------------------------- -1159 $convert-data:check0: -1160 # if (slice-empty?(word-slice)) break -1161 # . EAX = slice-empty?(word-slice) + 893 68/push "F - test-convert-code-and-data-segments/1"/imm32 + 894 68/push "e8 20 00 00 00 # e8/call 20/disp32"/imm32 + 895 68/push _test-output-stream/imm32 + 896 # . . call + 897 e8/call check-next-stream-line-equal/disp32 + 898 # . . discard args + 899 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP + 900 # . check-next-stream-line-equal(_test-output-stream, "68 20 # 68/push 0x20/imm8", msg) + 901 # . . push args + 902 68/push "F - test-convert-code-and-data-segments/2"/imm32 + 903 68/push "68 20 # 68/push 0x20/imm8"/imm32 + 904 68/push _test-output-stream/imm32 + 905 # . . call + 906 e8/call check-next-stream-line-equal/disp32 + 907 # . . discard args + 908 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP + 909 # . check-next-stream-line-equal(_test-output-stream, "== data", msg) + 910 # . . push args + 911 68/push "F - test-convert-code-and-data-segments/3"/imm32 + 912 68/push "== data"/imm32 + 913 68/push _test-output-stream/imm32 + 914 # . . call + 915 e8/call check-next-stream-line-equal/disp32 + 916 # . . discard args + 917 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP + 918 # . check-next-stream-line-equal(_test-output-stream, "03 04 00 00 00 ", msg) + 919 # . . push args + 920 68/push "F - test-convert-code-and-data-segments/4"/imm32 + 921 68/push "03 04 00 00 00 "/imm32 + 922 68/push _test-output-stream/imm32 + 923 # . . call + 924 e8/call check-next-stream-line-equal/disp32 + 925 # . . discard args + 926 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP + 927 # . epilog + 928 89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . . # copy EBP to ESP + 929 5d/pop-to-EBP + 930 c3/return + 931 + 932 convert-data: # line : (address stream byte), out : (address buffered-file) -> <void> + 933 # pseudocode: + 934 # var word-slice = {0, 0} + 935 # while true + 936 # word-slice = next-word(line) + 937 # if slice-empty?(word-slice) # end of file (maybe including trailing whitespace) + 938 # break # skip emitting some whitespace + 939 # if slice-starts-with?(word-slice, "#") # comment + 940 # write-slice(out, word-slice) + 941 # break + 942 # if slice-ends-with?(word-slice, ":") # label + 943 # write-stream-data(out, line) + 944 # break + 945 # if has-metadata?(word-slice, "imm32") + 946 # emit(out, word-slice, 4) + 947 # # disp32 is not permitted in data segments, and anything else is only a byte long + 948 # else + 949 # emit(out, word-slice, 1) + 950 # + 951 # . prolog + 952 55/push-EBP + 953 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP + 954 # . save registers + 955 50/push-EAX + 956 51/push-ECX + 957 52/push-EDX + 958 # var word-slice/ECX = {0, 0} + 959 68/push 0/imm32/end + 960 68/push 0/imm32/start + 961 89/copy 3/mod/direct 1/rm32/ECX . . . 4/r32/ESP . . # copy ESP to ECX + 962 +-- 26 lines: #? # dump line ----------------------------------------------------------------------------------------------------------------------------- + 988 $convert-data:loop: + 989 # next-word(line, word-slice) + 990 # . . push args + 991 51/push-ECX + 992 ff 6/subop/push 1/mod/*+disp8 5/rm32/EBP . . . . 8/disp8 . # push *(EBP+8) + 993 # . . call + 994 e8/call next-word/disp32 + 995 # . . discard args + 996 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP + 997 +-- 42 lines: #? # dump word-slice ----------------------------------------------------------------------------------------------------------------------- +1039 $convert-data:check0: +1040 # if (slice-empty?(word-slice)) break +1041 # . EAX = slice-empty?(word-slice) +1042 # . . push args +1043 51/push-ECX +1044 # . . call +1045 e8/call slice-empty?/disp32 +1046 # . . discard args +1047 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP +1048 # . if (EAX != 0) break +1049 3d/compare-EAX-and 0/imm32 +1050 0f 85/jump-if-not-equal $convert-data:break/disp32 +1051 $convert-data:check-for-comment: +1052 # if (slice-starts-with?(word-slice, "#")) +1053 # . start/EDX = word-slice->start +1054 8b/copy 0/mod/indirect 1/rm32/ECX . . . 2/r32/EDX . . # copy *ECX to EDX +1055 # . c/EAX = *start +1056 31/xor 3/mod/direct 0/rm32/EAX . . . 0/r32/EAX . . # clear EAX +1057 8a/copy-byte 0/mod/indirect 2/rm32/EDX . . . 0/r32/AL . . # copy byte at *EDX to AL +1058 # . if (EAX != '#') goto next check +1059 3d/compare-EAX-and 0x23/imm32/hash +1060 75/jump-if-not-equal $convert-data:check-for-label/disp8 +1061 $convert-data:comment: +1062 # write-slice(out, word-slice) +1063 # . . push args +1064 51/push-ECX +1065 ff 6/subop/push 1/mod/*+disp8 5/rm32/EBP . . . . 0xc/disp8 . # push *(EBP+12) +1066 # . . call +1067 e8/call write-slice/disp32 +1068 # . . discard args +1069 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP +1070 # break +1071 75/jump-if-not-equal $convert-data:break/disp8 +1072 $convert-data:check-for-label: +1073 # if (slice-ends-with?(word-slice, ":")) +1074 # . end/EDX = word-slice->end +1075 8b/copy 1/mod/*+disp8 1/rm32/ECX . . . 2/r32/EDX 4/disp8 . # copy *(ECX+4) to EDX +1076 # . c/EAX = *(end-1) +1077 31/xor 3/mod/direct 0/rm32/EAX . . . 0/r32/EAX . . # clear EAX +1078 8a/copy-byte 1/mod/*+disp8 2/rm32/EDX . . . 0/r32/AL -1/disp8 . # copy byte at *ECX to AL +1079 # . if (EAX != ':') goto next check +1080 3d/compare-EAX-and 0x3a/imm32/colon +1081 75/jump-if-not-equal $convert-data:check-for-imm32/disp8 +1082 $convert-data:label: +1083 # write-stream-data(out, line) +1084 # . . push args +1085 ff 6/subop/push 1/mod/*+disp8 5/rm32/EBP . . . . 8/disp8 . # push *(EBP+8) +1086 ff 6/subop/push 1/mod/*+disp8 5/rm32/EBP . . . . 0xc/disp8 . # push *(EBP+12) +1087 # . . call +1088 e8/call write-stream-data/disp32 +1089 # . . discard args +1090 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP +1091 # break +1092 75/jump-if-not-equal $convert-data:break/disp8 +1093 $convert-data:check-for-imm32: +1094 # if (has-metadata?(word-slice, "imm32")) +1095 # . EAX = has-metadata?(ECX, "imm32") +1096 # . . push args +1097 68/push "imm32"/imm32 +1098 51/push-ECX +1099 # . . call +1100 e8/call has-metadata?/disp32 +1101 # . . discard args +1102 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP +1103 # . if (EAX == 0) process as a single byte +1104 3d/compare-EAX-and 0/imm32 +1105 74/jump-if-equal $convert-data:single-byte/disp8 +1106 $convert-data:imm32: +1107 # emit(out, word-slice, 4) +1108 # . . push args +1109 68/push 4/imm32 +1110 51/push-ECX +1111 ff 6/subop/push 1/mod/*+disp8 5/rm32/EBP . . . . 0xc/disp8 . # push *(EBP+12) +1112 # . . call +1113 e8/call emit/disp32 +1114 # . . discard args +1115 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP +1116 e9/jump $convert-data:loop/disp32 +1117 $convert-data:single-byte: +1118 # emit(out, word-slice, 1) +1119 # . . push args +1120 68/push 1/imm32 +1121 51/push-ECX +1122 ff 6/subop/push 1/mod/*+disp8 5/rm32/EBP . . . . 0xc/disp8 . # push *(EBP+12) +1123 # . . call +1124 e8/call emit/disp32 +1125 # . . discard args +1126 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP +1127 e9/jump $convert-data:loop/disp32 +1128 $convert-data:break: +1129 $convert-data:end: +1130 # . reclaim locals +1131 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP +1132 # . restore registers +1133 5a/pop-to-EDX +1134 59/pop-to-ECX +1135 58/pop-to-EAX +1136 # . epilog +1137 89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . . # copy EBP to ESP +1138 5d/pop-to-EBP +1139 c3/return +1140 +1141 test-convert-data-passes-comments-through: +1142 # if a line starts with '#', pass it along unchanged +1143 # . prolog +1144 55/push-EBP +1145 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP +1146 # setup +1147 # . clear-stream(_test-input-stream) +1148 # . . push args +1149 68/push _test-input-stream/imm32 +1150 # . . call +1151 e8/call clear-stream/disp32 +1152 # . . discard args +1153 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP +1154 # . clear-stream(_test-output-stream) +1155 # . . push args +1156 68/push _test-output-stream/imm32 +1157 # . . call +1158 e8/call clear-stream/disp32 +1159 # . . discard args +1160 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP +1161 # . clear-stream(_test-output-buffered-file+4) 1162 # . . push args -1163 51/push-ECX -1164 # . . call -1165 e8/call slice-empty?/disp32 -1166 # . . discard args -1167 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP -1168 # . if (EAX != 0) break -1169 3d/compare-EAX-and 0/imm32 -1170 0f 85/jump-if-not-equal $convert-data:break/disp32 -1171 $convert-data:check-for-comment: -1172 # if (slice-starts-with?(word-slice, "#")) -1173 # . start/EDX = word-slice->start -1174 8b/copy 0/mod/indirect 1/rm32/ECX . . . 2/r32/EDX . . # copy *ECX to EDX -1175 # . c/EAX = *start -1176 31/xor 3/mod/direct 0/rm32/EAX . . . 0/r32/EAX . . # clear EAX -1177 8a/copy-byte 0/mod/indirect 2/rm32/EDX . . . 0/r32/AL . . # copy byte at *EDX to AL -1178 # . if (EAX != '#') goto next check -1179 3d/compare-EAX-and 0x23/imm32/hash -1180 75/jump-if-not-equal $convert-data:check-for-label/disp8 -1181 $convert-data:comment: -1182 # write-slice(out, word-slice) -1183 # . . push args -1184 51/push-ECX -1185 ff 6/subop/push 1/mod/*+disp8 5/rm32/EBP . . . . 0xc/disp8 . # push *(EBP+12) -1186 # . . call -1187 e8/call write-slice/disp32 -1188 # . . discard args -1189 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP -1190 # break -1191 75/jump-if-not-equal $convert-data:break/disp8 -1192 $convert-data:check-for-label: -1193 # if (slice-ends-with?(word-slice, ":")) -1194 # . end/EDX = word-slice->end -1195 8b/copy 1/mod/*+disp8 1/rm32/ECX . . . 2/r32/EDX 4/disp8 . # copy *(ECX+4) to EDX -1196 # . c/EAX = *(end-1) -1197 31/xor 3/mod/direct 0/rm32/EAX . . . 0/r32/EAX . . # clear EAX -1198 8a/copy-byte 1/mod/*+disp8 2/rm32/EDX . . . 0/r32/AL -1/disp8 . # copy byte at *ECX to AL -1199 # . if (EAX != ':') goto next check -1200 3d/compare-EAX-and 0x3a/imm32/colon -1201 75/jump-if-not-equal $convert-data:check-for-imm32/disp8 -1202 $convert-data:label: -1203 # write-stream-data(out, line) -1204 # . . push args -1205 ff 6/subop/push 1/mod/*+disp8 5/rm32/EBP . . . . 8/disp8 . # push *(EBP+8) -1206 ff 6/subop/push 1/mod/*+disp8 5/rm32/EBP . . . . 0xc/disp8 . # push *(EBP+12) -1207 # . . call -1208 e8/call write-stream-data/disp32 -1209 # . . discard args -1210 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP -1211 # break -1212 75/jump-if-not-equal $convert-data:break/disp8 -1213 $convert-data:check-for-imm32: -1214 # if (has-metadata?(word-slice, "imm32")) -1215 # . EAX = has-metadata?(ECX, "imm32") -1216 # . . push args -1217 68/push "imm32"/imm32 -1218 51/push-ECX -1219 # . . call -1220 e8/call has-metadata?/disp32 -1221 # . . discard args -1222 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP -1223 # . if (EAX == 0) process as a single byte -1224 3d/compare-EAX-and 0/imm32 -1225 74/jump-if-equal $convert-data:single-byte/disp8 -1226 $convert-data:imm32: -1227 # emit(out, word-slice, 4) -1228 # . . push args -1229 68/push 4/imm32 -1230 51/push-ECX -1231 ff 6/subop/push 1/mod/*+disp8 5/rm32/EBP . . . . 0xc/disp8 . # push *(EBP+12) -1232 # . . call -1233 e8/call emit/disp32 -1234 # . . discard args -1235 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP -1236 e9/jump $convert-data:loop/disp32 -1237 $convert-data:single-byte: -1238 # emit(out, word-slice, 1) -1239 # . . push args -1240 68/push 1/imm32 -1241 51/push-ECX -1242 ff 6/subop/push 1/mod/*+disp8 5/rm32/EBP . . . . 0xc/disp8 . # push *(EBP+12) -1243 # . . call -1244 e8/call emit/disp32 -1245 # . . discard args -1246 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP -1247 e9/jump $convert-data:loop/disp32 -1248 $convert-data:break: -1249 $convert-data:end: -1250 # . reclaim locals -1251 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP -1252 # . restore registers -1253 5a/pop-to-EDX -1254 59/pop-to-ECX -1255 58/pop-to-EAX -1256 # . epilog -1257 89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . . # copy EBP to ESP -1258 5d/pop-to-EBP -1259 c3/return -1260 -1261 test-convert-data-passes-comments-through: -1262 # if a line starts with '#', pass it along unchanged -1263 # . prolog -1264 55/push-EBP -1265 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP -1266 # setup -1267 # . clear-stream(_test-input-stream) -1268 # . . push args -1269 68/push _test-input-stream/imm32 -1270 # . . call -1271 e8/call clear-stream/disp32 -1272 # . . discard args -1273 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP -1274 # . clear-stream(_test-output-stream) -1275 # . . push args -1276 68/push _test-output-stream/imm32 +1163 b8/copy-to-EAX _test-output-buffered-file/imm32 +1164 05/add-to-EAX 4/imm32 +1165 50/push-EAX +1166 # . . call +1167 e8/call clear-stream/disp32 +1168 # . . discard args +1169 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP +1170 # initialize input +1171 # . write(_test-input-stream, "# abcd") +1172 # . . push args +1173 68/push "# abcd"/imm32 +1174 68/push _test-input-stream/imm32 +1175 # . . call +1176 e8/call write/disp32 +1177 # . . discard args +1178 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP +1179 # convert-data(_test-input-stream, _test-output-buffered-file) +1180 # . . push args +1181 68/push _test-output-buffered-file/imm32 +1182 68/push _test-input-stream/imm32 +1183 # . . call +1184 e8/call convert-data/disp32 +1185 # . . discard args +1186 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP +1187 # check that the line just passed through +1188 # . flush(_test-output-buffered-file) +1189 # . . push args +1190 68/push _test-output-buffered-file/imm32 +1191 # . . call +1192 e8/call flush/disp32 +1193 # . . discard args +1194 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP +1195 +-- 26 lines: #? # dump output --------------------------------------------------------------------------------------------------------------------------- +1221 # . check-stream-equal(_test-output-stream, "# abcd", msg) +1222 # . . push args +1223 68/push "F - test-convert-data-passes-comments-through"/imm32 +1224 68/push "# abcd"/imm32 +1225 68/push _test-output-stream/imm32 +1226 # . . call +1227 e8/call check-stream-equal/disp32 +1228 # . . discard args +1229 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP +1230 # . epilog +1231 89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . . # copy EBP to ESP +1232 5d/pop-to-EBP +1233 c3/return +1234 +1235 test-convert-data-passes-labels-through: +1236 # if the first word ends with ':', pass along the entire line unchanged +1237 # . prolog +1238 55/push-EBP +1239 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP +1240 # setup +1241 # . clear-stream(_test-input-stream) +1242 # . . push args +1243 68/push _test-input-stream/imm32 +1244 # . . call +1245 e8/call clear-stream/disp32 +1246 # . . discard args +1247 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP +1248 # . clear-stream(_test-output-stream) +1249 # . . push args +1250 68/push _test-output-stream/imm32 +1251 # . . call +1252 e8/call clear-stream/disp32 +1253 # . . discard args +1254 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP +1255 # . clear-stream(_test-output-buffered-file+4) +1256 # . . push args +1257 b8/copy-to-EAX _test-output-buffered-file/imm32 +1258 05/add-to-EAX 4/imm32 +1259 50/push-EAX +1260 # . . call +1261 e8/call clear-stream/disp32 +1262 # . . discard args +1263 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP +1264 # initialize input +1265 # . write(_test-input-stream, "ab: # cd") +1266 # . . push args +1267 68/push "ab: # cd"/imm32 +1268 68/push _test-input-stream/imm32 +1269 # . . call +1270 e8/call write/disp32 +1271 # . . discard args +1272 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP +1273 # convert-data(_test-input-stream, _test-output-buffered-file) +1274 # . . push args +1275 68/push _test-output-buffered-file/imm32 +1276 68/push _test-input-stream/imm32 1277 # . . call -1278 e8/call clear-stream/disp32 +1278 e8/call convert-data/disp32 1279 # . . discard args -1280 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP -1281 # . clear-stream(_test-output-buffered-file+4) -1282 # . . push args -1283 b8/copy-to-EAX _test-output-buffered-file/imm32 -1284 05/add-to-EAX 4/imm32 -1285 50/push-EAX -1286 # . . call -1287 e8/call clear-stream/disp32 -1288 # . . discard args -1289 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP -1290 # initialize input -1291 # . write(_test-input-stream, "# abcd") -1292 # . . push args -1293 68/push "# abcd"/imm32 -1294 68/push _test-input-stream/imm32 -1295 # . . call -1296 e8/call write/disp32 -1297 # . . discard args -1298 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP -1299 # convert-data(_test-input-stream, _test-output-buffered-file) -1300 # . . push args -1301 68/push _test-output-buffered-file/imm32 -1302 68/push _test-input-stream/imm32 -1303 # . . call -1304 e8/call convert-data/disp32 -1305 # . . discard args -1306 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP -1307 # check that the line just passed through -1308 # . flush(_test-output-buffered-file) -1309 # . . push args -1310 68/push _test-output-buffered-file/imm32 -1311 # . . call -1312 e8/call flush/disp32 -1313 # . . discard args -1314 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP -1315 +-- 34 lines: #? # dump output --------------------------------------------------------------------------------------------------------------------------- -1349 # . check-stream-equal(_test-output-stream, "# abcd", msg) -1350 # . . push args -1351 68/push "F - test-convert-data-passes-comments-through"/imm32 -1352 68/push "# abcd"/imm32 -1353 68/push _test-output-stream/imm32 +1280 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP +1281 # check that the line just passed through +1282 # . flush(_test-output-buffered-file) +1283 # . . push args +1284 68/push _test-output-buffered-file/imm32 +1285 # . . call +1286 e8/call flush/disp32 +1287 # . . discard args +1288 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP +1289 # . check-stream-equal(_test-output-stream, "ab: # cd", msg) +1290 # . . push args +1291 68/push "F - test-convert-data-passes-labels-through"/imm32 +1292 68/push "ab: # cd"/imm32 +1293 68/push _test-output-stream/imm32 +1294 # . . call +1295 e8/call check-stream-equal/disp32 +1296 # . . discard args +1297 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP +1298 # . epilog +1299 89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . . # copy EBP to ESP +1300 5d/pop-to-EBP +1301 c3/return +1302 +1303 test-convert-data-passes-names-through: +1304 # If a word is a valid name, just emit it unchanged. +1305 # Later phases will deal with it. +1306 # . prolog +1307 55/push-EBP +1308 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP +1309 # setup +1310 # . clear-stream(_test-input-stream) +1311 # . . push args +1312 68/push _test-input-stream/imm32 +1313 # . . call +1314 e8/call clear-stream/disp32 +1315 # . . discard args +1316 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP +1317 # . clear-stream(_test-output-stream) +1318 # . . push args +1319 68/push _test-output-stream/imm32 +1320 # . . call +1321 e8/call clear-stream/disp32 +1322 # . . discard args +1323 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP +1324 # . clear-stream(_test-output-buffered-file+4) +1325 # . . push args +1326 b8/copy-to-EAX _test-output-buffered-file/imm32 +1327 05/add-to-EAX 4/imm32 +1328 50/push-EAX +1329 # . . call +1330 e8/call clear-stream/disp32 +1331 # . . discard args +1332 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP +1333 # initialize input +1334 # . write(_test-input-stream, "abcd/imm32") +1335 # . . push args +1336 68/push "abcd/imm32"/imm32 +1337 68/push _test-input-stream/imm32 +1338 # . . call +1339 e8/call write/disp32 +1340 # . . discard args +1341 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP +1342 # convert-data(_test-input-stream, _test-output-buffered-file) +1343 # . . push args +1344 68/push _test-output-buffered-file/imm32 +1345 68/push _test-input-stream/imm32 +1346 # . . call +1347 e8/call convert-data/disp32 +1348 # . . discard args +1349 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP +1350 # check that the line just passed through +1351 # . flush(_test-output-buffered-file) +1352 # . . push args +1353 68/push _test-output-buffered-file/imm32 1354 # . . call -1355 e8/call check-stream-equal/disp32 +1355 e8/call flush/disp32 1356 # . . discard args -1357 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP -1358 # . epilog -1359 89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . . # copy EBP to ESP -1360 5d/pop-to-EBP -1361 c3/return -1362 -1363 test-convert-data-passes-labels-through: -1364 # if the first word ends with ':', pass along the entire line unchanged -1365 # . prolog -1366 55/push-EBP -1367 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP -1368 # setup -1369 # . clear-stream(_test-input-stream) -1370 # . . push args -1371 68/push _test-input-stream/imm32 -1372 # . . call -1373 e8/call clear-stream/disp32 -1374 # . . discard args -1375 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP -1376 # . clear-stream(_test-output-stream) -1377 # . . push args -1378 68/push _test-output-stream/imm32 -1379 # . . call -1380 e8/call clear-stream/disp32 -1381 # . . discard args -1382 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP -1383 # . clear-stream(_test-output-buffered-file+4) -1384 # . . push args -1385 b8/copy-to-EAX _test-output-buffered-file/imm32 -1386 05/add-to-EAX 4/imm32 -1387 50/push-EAX +1357 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP +1358 # . check-stream-equal(_test-output-stream, "abcd/imm32", msg) +1359 # . . push args +1360 68/push "F - test-convert-data-passes-names-through"/imm32 +1361 68/push "abcd/imm32 "/imm32 +1362 68/push _test-output-stream/imm32 +1363 # . . call +1364 e8/call check-stream-equal/disp32 +1365 # . . discard args +1366 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP +1367 # . epilog +1368 89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . . # copy EBP to ESP +1369 5d/pop-to-EBP +1370 c3/return +1371 +1372 test-convert-data-handles-imm32: +1373 # If a word has the /imm32 metadata, emit it in 4 bytes. +1374 # . prolog +1375 55/push-EBP +1376 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP +1377 # setup +1378 # . clear-stream(_test-input-stream) +1379 # . . push args +1380 68/push _test-input-stream/imm32 +1381 # . . call +1382 e8/call clear-stream/disp32 +1383 # . . discard args +1384 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP +1385 # . clear-stream(_test-output-stream) +1386 # . . push args +1387 68/push _test-output-stream/imm32 1388 # . . call 1389 e8/call clear-stream/disp32 1390 # . . discard args 1391 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP -1392 # initialize input -1393 # . write(_test-input-stream, "ab: # cd") -1394 # . . push args -1395 68/push "ab: # cd"/imm32 -1396 68/push _test-input-stream/imm32 +1392 # . clear-stream(_test-output-buffered-file+4) +1393 # . . push args +1394 b8/copy-to-EAX _test-output-buffered-file/imm32 +1395 05/add-to-EAX 4/imm32 +1396 50/push-EAX 1397 # . . call -1398 e8/call write/disp32 +1398 e8/call clear-stream/disp32 1399 # . . discard args -1400 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP -1401 # convert-data(_test-input-stream, _test-output-buffered-file) -1402 # . . push args -1403 68/push _test-output-buffered-file/imm32 -1404 68/push _test-input-stream/imm32 -1405 # . . call -1406 e8/call convert-data/disp32 -1407 # . . discard args -1408 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP -1409 # check that the line just passed through -1410 # . flush(_test-output-buffered-file) +1400 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP +1401 # initialize input +1402 # . write(_test-input-stream, "30/imm32") +1403 # . . push args +1404 68/push "30/imm32"/imm32 +1405 68/push _test-input-stream/imm32 +1406 # . . call +1407 e8/call write/disp32 +1408 # . . discard args +1409 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP +1410 # convert-data(_test-input-stream, _test-output-buffered-file) 1411 # . . push args -1412 68/push _test-output-buffered-file/imm32 -1413 # . . call -1414 e8/call flush/disp32 -1415 # . . discard args -1416 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP -1417 # . check-stream-equal(_test-output-stream, "ab: # cd", msg) -1418 # . . push args -1419 68/push "F - test-convert-data-passes-labels-through"/imm32 -1420 68/push "ab: # cd"/imm32 -1421 68/push _test-output-stream/imm32 +1412 68/push _test-output-buffered-file/imm32 +1413 68/push _test-input-stream/imm32 +1414 # . . call +1415 e8/call convert-data/disp32 +1416 # . . discard args +1417 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP +1418 # check that 4 bytes were written +1419 # . flush(_test-output-buffered-file) +1420 # . . push args +1421 68/push _test-output-buffered-file/imm32 1422 # . . call -1423 e8/call check-stream-equal/disp32 +1423 e8/call flush/disp32 1424 # . . discard args -1425 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP -1426 # . epilog -1427 89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . . # copy EBP to ESP -1428 5d/pop-to-EBP -1429 c3/return -1430 -1431 test-convert-data-passes-names-through: -1432 # If a word is a valid name, just emit it unchanged. -1433 # Later phases will deal with it. -1434 # . prolog -1435 55/push-EBP -1436 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP -1437 # setup -1438 # . clear-stream(_test-input-stream) -1439 # . . push args -1440 68/push _test-input-stream/imm32 -1441 # . . call -1442 e8/call clear-stream/disp32 -1443 # . . discard args -1444 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP -1445 # . clear-stream(_test-output-stream) -1446 # . . push args -1447 68/push _test-output-stream/imm32 -1448 # . . call -1449 e8/call clear-stream/disp32 -1450 # . . discard args -1451 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP -1452 # . clear-stream(_test-output-buffered-file+4) -1453 # . . push args -1454 b8/copy-to-EAX _test-output-buffered-file/imm32 -1455 05/add-to-EAX 4/imm32 -1456 50/push-EAX +1425 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP +1426 # . check-stream-equal(_test-output-stream, "30 00 00 00 ", msg) +1427 # . . push args +1428 68/push "F - test-convert-data-handles-imm32"/imm32 +1429 68/push "30 00 00 00 "/imm32 +1430 68/push _test-output-stream/imm32 +1431 # . . call +1432 e8/call check-stream-equal/disp32 +1433 # . . discard args +1434 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP +1435 # . epilog +1436 89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . . # copy EBP to ESP +1437 5d/pop-to-EBP +1438 c3/return +1439 +1440 test-convert-data-handles-single-byte: +1441 # Any metadata but /imm32 will emit a single byte. +1442 # Data segments can't have /disp32, and SubX doesn't support 16-bit operands. +1443 # . prolog +1444 55/push-EBP +1445 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP +1446 # setup +1447 # . clear-stream(_test-input-stream) +1448 # . . push args +1449 68/push _test-input-stream/imm32 +1450 # . . call +1451 e8/call clear-stream/disp32 +1452 # . . discard args +1453 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP +1454 # . clear-stream(_test-output-stream) +1455 # . . push args +1456 68/push _test-output-stream/imm32 1457 # . . call 1458 e8/call clear-stream/disp32 1459 # . . discard args 1460 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP -1461 # initialize input -1462 # . write(_test-input-stream, "abcd/imm32") -1463 # . . push args -1464 68/push "abcd/imm32"/imm32 -1465 68/push _test-input-stream/imm32 +1461 # . clear-stream(_test-output-buffered-file+4) +1462 # . . push args +1463 b8/copy-to-EAX _test-output-buffered-file/imm32 +1464 05/add-to-EAX 4/imm32 +1465 50/push-EAX 1466 # . . call -1467 e8/call write/disp32 +1467 e8/call clear-stream/disp32 1468 # . . discard args -1469 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP -1470 # convert-data(_test-input-stream, _test-output-buffered-file) -1471 # . . push args -1472 68/push _test-output-buffered-file/imm32 -1473 68/push _test-input-stream/imm32 -1474 # . . call -1475 e8/call convert-data/disp32 -1476 # . . discard args -1477 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP -1478 # check that the line just passed through -1479 # . flush(_test-output-buffered-file) +1469 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP +1470 # initialize input +1471 # . write(_test-input-stream, "30/imm16") +1472 # . . push args +1473 68/push "30/imm16"/imm32 +1474 68/push _test-input-stream/imm32 +1475 # . . call +1476 e8/call write/disp32 +1477 # . . discard args +1478 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP +1479 # convert-data(_test-input-stream, _test-output-buffered-file) 1480 # . . push args -1481 68/push _test-output-buffered-file/imm32 -1482 # . . call -1483 e8/call flush/disp32 -1484 # . . discard args -1485 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP -1486 # . check-stream-equal(_test-output-stream, "abcd/imm32", msg) -1487 # . . push args -1488 68/push "F - test-convert-data-passes-names-through"/imm32 -1489 68/push "abcd/imm32 "/imm32 -1490 68/push _test-output-stream/imm32 +1481 68/push _test-output-buffered-file/imm32 +1482 68/push _test-input-stream/imm32 +1483 # . . call +1484 e8/call convert-data/disp32 +1485 # . . discard args +1486 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP +1487 # check that a single byte was written (imm16 is not a valid operand type) +1488 # . flush(_test-output-buffered-file) +1489 # . . push args +1490 68/push _test-output-buffered-file/imm32 1491 # . . call -1492 e8/call check-stream-equal/disp32 +1492 e8/call flush/disp32 1493 # . . discard args -1494 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP -1495 # . epilog -1496 89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . . # copy EBP to ESP -1497 5d/pop-to-EBP -1498 c3/return -1499 -1500 test-convert-data-handles-imm32: -1501 # If a word has the /imm32 metadata, emit it in 4 bytes. -1502 # . prolog -1503 55/push-EBP -1504 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP -1505 # setup -1506 # . clear-stream(_test-input-stream) -1507 # . . push args -1508 68/push _test-input-stream/imm32 -1509 # . . call -1510 e8/call clear-stream/disp32 -1511 # . . discard args -1512 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP -1513 # . clear-stream(_test-output-stream) -1514 # . . push args -1515 68/push _test-output-stream/imm32 -1516 # . . call -1517 e8/call clear-stream/disp32 -1518 # . . discard args -1519 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP -1520 # . clear-stream(_test-output-buffered-file+4) -1521 # . . push args -1522 b8/copy-to-EAX _test-output-buffered-file/imm32 -1523 05/add-to-EAX 4/imm32 -1524 50/push-EAX +1494 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP +1495 # . check-stream-equal(_test-output-stream, "30 ", msg) +1496 # . . push args +1497 68/push "F - test-convert-data-handles-single-byte"/imm32 +1498 68/push "30 "/imm32 +1499 68/push _test-output-stream/imm32 +1500 # . . call +1501 e8/call check-stream-equal/disp32 +1502 # . . discard args +1503 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP +1504 # . epilog +1505 89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . . # copy EBP to ESP +1506 5d/pop-to-EBP +1507 c3/return +1508 +1509 test-convert-data-multiple-bytes: +1510 # Multiple single-byte words in input stream get processed one by one. +1511 # . prolog +1512 55/push-EBP +1513 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP +1514 # setup +1515 # . clear-stream(_test-input-stream) +1516 # . . push args +1517 68/push _test-input-stream/imm32 +1518 # . . call +1519 e8/call clear-stream/disp32 +1520 # . . discard args +1521 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP +1522 # . clear-stream(_test-output-stream) +1523 # . . push args +1524 68/push _test-output-stream/imm32 1525 # . . call 1526 e8/call clear-stream/disp32 1527 # . . discard args 1528 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP -1529 # initialize input -1530 # . write(_test-input-stream, "30/imm32") -1531 # . . push args -1532 68/push "30/imm32"/imm32 -1533 68/push _test-input-stream/imm32 +1529 # . clear-stream(_test-output-buffered-file+4) +1530 # . . push args +1531 b8/copy-to-EAX _test-output-buffered-file/imm32 +1532 05/add-to-EAX 4/imm32 +1533 50/push-EAX 1534 # . . call -1535 e8/call write/disp32 +1535 e8/call clear-stream/disp32 1536 # . . discard args -1537 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP -1538 # convert-data(_test-input-stream, _test-output-buffered-file) -1539 # . . push args -1540 68/push _test-output-buffered-file/imm32 -1541 68/push _test-input-stream/imm32 -1542 # . . call -1543 e8/call convert-data/disp32 -1544 # . . discard args -1545 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP -1546 # check that 4 bytes were written -1547 # . flush(_test-output-buffered-file) +1537 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP +1538 # initialize input +1539 # . write(_test-input-stream, "1 2") +1540 # . . push args +1541 68/push "1 2"/imm32 +1542 68/push _test-input-stream/imm32 +1543 # . . call +1544 e8/call write/disp32 +1545 # . . discard args +1546 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP +1547 # convert-data(_test-input-stream, _test-output-buffered-file) 1548 # . . push args -1549 68/push _test-output-buffered-file/imm32 -1550 # . . call -1551 e8/call flush/disp32 -1552 # . . discard args -1553 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP -1554 # . check-stream-equal(_test-output-stream, "30 00 00 00 ", msg) -1555 # . . push args -1556 68/push "F - test-convert-data-handles-imm32"/imm32 -1557 68/push "30 00 00 00 "/imm32 -1558 68/push _test-output-stream/imm32 +1549 68/push _test-output-buffered-file/imm32 +1550 68/push _test-input-stream/imm32 +1551 # . . call +1552 e8/call convert-data/disp32 +1553 # . . discard args +1554 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP +1555 # check output +1556 # . flush(_test-output-buffered-file) +1557 # . . push args +1558 68/push _test-output-buffered-file/imm32 1559 # . . call -1560 e8/call check-stream-equal/disp32 +1560 e8/call flush/disp32 1561 # . . discard args -1562 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP -1563 # . epilog -1564 89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . . # copy EBP to ESP -1565 5d/pop-to-EBP -1566 c3/return -1567 -1568 test-convert-data-handles-single-byte: -1569 # Any metadata but /imm32 will emit a single byte. -1570 # Data segments can't have /disp32, and SubX doesn't support 16-bit operands. -1571 # . prolog -1572 55/push-EBP -1573 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP -1574 # setup -1575 # . clear-stream(_test-input-stream) -1576 # . . push args -1577 68/push _test-input-stream/imm32 -1578 # . . call -1579 e8/call clear-stream/disp32 -1580 # . . discard args -1581 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP -1582 # . clear-stream(_test-output-stream) -1583 # . . push args -1584 68/push _test-output-stream/imm32 -1585 # . . call -1586 e8/call clear-stream/disp32 -1587 # . . discard args -1588 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP -1589 # . clear-stream(_test-output-buffered-file+4) -1590 # . . push args -1591 b8/copy-to-EAX _test-output-buffered-file/imm32 -1592 05/add-to-EAX 4/imm32 -1593 50/push-EAX -1594 # . . call -1595 e8/call clear-stream/disp32 -1596 # . . discard args -1597 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP -1598 # initialize input -1599 # . write(_test-input-stream, "30/imm16") -1600 # . . push args -1601 68/push "30/imm16"/imm32 -1602 68/push _test-input-stream/imm32 -1603 # . . call -1604 e8/call write/disp32 -1605 # . . discard args -1606 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP -1607 # convert-data(_test-input-stream, _test-output-buffered-file) +1562 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP +1563 # . check-stream-equal(_test-output-stream, "01 02 ", msg) +1564 # . . push args +1565 68/push "F - test-convert-data-multiple-bytes"/imm32 +1566 68/push "01 02 "/imm32 +1567 68/push _test-output-stream/imm32 +1568 # . . call +1569 e8/call check-stream-equal/disp32 +1570 # . . discard args +1571 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP +1572 # . epilog +1573 89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . . # copy EBP to ESP +1574 5d/pop-to-EBP +1575 c3/return +1576 +1577 test-convert-data-byte-then-name: +1578 # Single-byte word followed by valid name get processed one by one. +1579 # . prolog +1580 55/push-EBP +1581 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP +1582 # setup +1583 # . clear-stream(_test-input-stream) +1584 # . . push args +1585 68/push _test-input-stream/imm32 +1586 # . . call +1587 e8/call clear-stream/disp32 +1588 # . . discard args +1589 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP +1590 # . clear-stream(_test-output-stream) +1591 # . . push args +1592 68/push _test-output-stream/imm32 +1593 # . . call +1594 e8/call clear-stream/disp32 +1595 # . . discard args +1596 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP +1597 # . clear-stream(_test-output-buffered-file+4) +1598 # . . push args +1599 b8/copy-to-EAX _test-output-buffered-file/imm32 +1600 05/add-to-EAX 4/imm32 +1601 50/push-EAX +1602 # . . call +1603 e8/call clear-stream/disp32 +1604 # . . discard args +1605 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP +1606 # initialize input +1607 # . write(_test-input-stream, "30 abcd/o") 1608 # . . push args -1609 68/push _test-output-buffered-file/imm32 -1610 68/push _test-input-stream/imm32 +1609 68/push "30 abcd/o"/imm32 +1610 68/push _test-input-stream/imm32 1611 # . . call -1612 e8/call convert-data/disp32 +1612 e8/call write/disp32 1613 # . . discard args 1614 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP -1615 # check that a single byte was written (imm16 is not a valid operand type) -1616 # . flush(_test-output-buffered-file) -1617 # . . push args -1618 68/push _test-output-buffered-file/imm32 +1615 # convert-data(_test-input-stream, _test-output-buffered-file) +1616 # . . push args +1617 68/push _test-output-buffered-file/imm32 +1618 68/push _test-input-stream/imm32 1619 # . . call -1620 e8/call flush/disp32 +1620 e8/call convert-data/disp32 1621 # . . discard args -1622 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP -1623 # . check-stream-equal(_test-output-stream, "30 ", msg) -1624 # . . push args -1625 68/push "F - test-convert-data-handles-single-byte"/imm32 -1626 68/push "30 "/imm32 -1627 68/push _test-output-stream/imm32 -1628 # . . call -1629 e8/call check-stream-equal/disp32 -1630 # . . discard args -1631 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP -1632 # . epilog -1633 89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . . # copy EBP to ESP -1634 5d/pop-to-EBP -1635 c3/return -1636 -1637 test-convert-data-multiple-bytes: -1638 # Multiple single-byte words in input stream get processed one by one. -1639 # . prolog -1640 55/push-EBP -1641 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP -1642 # setup -1643 # . clear-stream(_test-input-stream) -1644 # . . push args -1645 68/push _test-input-stream/imm32 -1646 # . . call -1647 e8/call clear-stream/disp32 -1648 # . . discard args -1649 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP -1650 # . clear-stream(_test-output-stream) -1651 # . . push args -1652 68/push _test-output-stream/imm32 -1653 # . . call -1654 e8/call clear-stream/disp32 -1655 # . . discard args -1656 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP -1657 # . clear-stream(_test-output-buffered-file+4) -1658 # . . push args -1659 b8/copy-to-EAX _test-output-buffered-file/imm32 -1660 05/add-to-EAX 4/imm32 -1661 50/push-EAX -1662 # . . call -1663 e8/call clear-stream/disp32 -1664 # . . discard args -1665 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP -1666 # initialize input -1667 # . write(_test-input-stream, "1 2") -1668 # . . push args -1669 68/push "1 2"/imm32 -1670 68/push _test-input-stream/imm32 -1671 # . . call -1672 e8/call write/disp32 -1673 # . . discard args -1674 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP -1675 # convert-data(_test-input-stream, _test-output-buffered-file) +1622 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP +1623 # check output +1624 # . flush(_test-output-buffered-file) +1625 # . . push args +1626 68/push _test-output-buffered-file/imm32 +1627 # . . call +1628 e8/call flush/disp32 +1629 # . . discard args +1630 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP +1631 # . check-stream-equal(_test-output-stream, "30 abcd/o ", msg) +1632 # . . push args +1633 68/push "F - test-convert-data-byte-then-name"/imm32 +1634 68/push "30 abcd/o "/imm32 +1635 68/push _test-output-stream/imm32 +1636 # . . call +1637 e8/call check-stream-equal/disp32 +1638 # . . discard args +1639 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP +1640 # . epilog +1641 89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . . # copy EBP to ESP +1642 5d/pop-to-EBP +1643 c3/return +1644 +1645 test-convert-data-multiple-words: +1646 # Multiple words in input stream get processed one by one. +1647 # . prolog +1648 55/push-EBP +1649 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP +1650 # setup +1651 # . clear-stream(_test-input-stream) +1652 # . . push args +1653 68/push _test-input-stream/imm32 +1654 # . . call +1655 e8/call clear-stream/disp32 +1656 # . . discard args +1657 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP +1658 # . clear-stream(_test-output-stream) +1659 # . . push args +1660 68/push _test-output-stream/imm32 +1661 # . . call +1662 e8/call clear-stream/disp32 +1663 # . . discard args +1664 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP +1665 # . clear-stream(_test-output-buffered-file+4) +1666 # . . push args +1667 b8/copy-to-EAX _test-output-buffered-file/imm32 +1668 05/add-to-EAX 4/imm32 +1669 50/push-EAX +1670 # . . call +1671 e8/call clear-stream/disp32 +1672 # . . discard args +1673 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP +1674 # initialize input +1675 # . write(_test-input-stream, "30 abcd/o 42e1/imm32") 1676 # . . push args -1677 68/push _test-output-buffered-file/imm32 -1678 68/push _test-input-stream/imm32 +1677 68/push "30 abcd/o 42e1/imm32"/imm32 +1678 68/push _test-input-stream/imm32 1679 # . . call -1680 e8/call convert-data/disp32 +1680 e8/call write/disp32 1681 # . . discard args 1682 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP -1683 # check output -1684 # . flush(_test-output-buffered-file) -1685 # . . push args -1686 68/push _test-output-buffered-file/imm32 +1683 # convert-data(_test-input-stream, _test-output-buffered-file) +1684 # . . push args +1685 68/push _test-output-buffered-file/imm32 +1686 68/push _test-input-stream/imm32 1687 # . . call -1688 e8/call flush/disp32 +1688 e8/call convert-data/disp32 1689 # . . discard args -1690 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP -1691 # . check-stream-equal(_test-output-stream, "01 02 ", msg) -1692 # . . push args -1693 68/push "F - test-convert-data-multiple-bytes"/imm32 -1694 68/push "01 02 "/imm32 -1695 68/push _test-output-stream/imm32 -1696 # . . call -1697 e8/call check-stream-equal/disp32 -1698 # . . discard args -1699 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP -1700 # . epilog -1701 89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . . # copy EBP to ESP -1702 5d/pop-to-EBP -1703 c3/return -1704 -1705 test-convert-data-byte-then-name: -1706 # Single-byte word followed by valid name get processed one by one. -1707 # . prolog -1708 55/push-EBP -1709 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP -1710 # setup -1711 # . clear-stream(_test-input-stream) -1712 # . . push args -1713 68/push _test-input-stream/imm32 -1714 # . . call -1715 e8/call clear-stream/disp32 -1716 # . . discard args -1717 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP -1718 # . clear-stream(_test-output-stream) -1719 # . . push args -1720 68/push _test-output-stream/imm32 -1721 # . . call -1722 e8/call clear-stream/disp32 -1723 # . . discard args -1724 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP -1725 # . clear-stream(_test-output-buffered-file+4) +1690 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP +1691 # check output +1692 # . flush(_test-output-buffered-file) +1693 # . . push args +1694 68/push _test-output-buffered-file/imm32 +1695 # . . call +1696 e8/call flush/disp32 +1697 # . . discard args +1698 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP +1699 +-- 26 lines: #? # dump output --------------------------------------------------------------------------------------------------------------------------- +1725 # . check-stream-equal(_test-output-stream, "30 abcd/o 42 e1 00 00 ", msg) 1726 # . . push args -1727 b8/copy-to-EAX _test-output-buffered-file/imm32 -1728 05/add-to-EAX 4/imm32 -1729 50/push-EAX +1727 68/push "F - test-convert-data-multiple-words"/imm32 +1728 68/push "30 abcd/o e1 42 00 00 "/imm32 +1729 68/push _test-output-stream/imm32 1730 # . . call -1731 e8/call clear-stream/disp32 +1731 e8/call check-stream-equal/disp32 1732 # . . discard args -1733 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP -1734 # initialize input -1735 # . write(_test-input-stream, "30 abcd/o") -1736 # . . push args -1737 68/push "30 abcd/o"/imm32 -1738 68/push _test-input-stream/imm32 -1739 # . . call -1740 e8/call write/disp32 -1741 # . . discard args -1742 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP -1743 # convert-data(_test-input-stream, _test-output-buffered-file) -1744 # . . push args -1745 68/push _test-output-buffered-file/imm32 -1746 68/push _test-input-stream/imm32 -1747 # . . call -1748 e8/call convert-data/disp32 -1749 # . . discard args -1750 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP -1751 # check output -1752 # . flush(_test-output-buffered-file) +1733 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP +1734 # . epilog +1735 89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . . # copy EBP to ESP +1736 5d/pop-to-EBP +1737 c3/return +1738 +1739 test-convert-data-trailing-comment: +1740 # Trailing comments in data segment get appropriately ignored. +1741 # . prolog +1742 55/push-EBP +1743 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP +1744 # setup +1745 # . clear-stream(_test-input-stream) +1746 # . . push args +1747 68/push _test-input-stream/imm32 +1748 # . . call +1749 e8/call clear-stream/disp32 +1750 # . . discard args +1751 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP +1752 # . clear-stream(_test-output-stream) 1753 # . . push args -1754 68/push _test-output-buffered-file/imm32 +1754 68/push _test-output-stream/imm32 1755 # . . call -1756 e8/call flush/disp32 +1756 e8/call clear-stream/disp32 1757 # . . discard args 1758 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP -1759 # . check-stream-equal(_test-output-stream, "30 abcd/o ", msg) +1759 # . clear-stream(_test-output-buffered-file+4) 1760 # . . push args -1761 68/push "F - test-convert-data-byte-then-name"/imm32 -1762 68/push "30 abcd/o "/imm32 -1763 68/push _test-output-stream/imm32 +1761 b8/copy-to-EAX _test-output-buffered-file/imm32 +1762 05/add-to-EAX 4/imm32 +1763 50/push-EAX 1764 # . . call -1765 e8/call check-stream-equal/disp32 +1765 e8/call clear-stream/disp32 1766 # . . discard args -1767 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP -1768 # . epilog -1769 89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . . # copy EBP to ESP -1770 5d/pop-to-EBP -1771 c3/return -1772 -1773 test-convert-data-multiple-words: -1774 # Multiple words in input stream get processed one by one. -1775 # . prolog -1776 55/push-EBP -1777 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP -1778 # setup -1779 # . clear-stream(_test-input-stream) -1780 # . . push args -1781 68/push _test-input-stream/imm32 -1782 # . . call -1783 e8/call clear-stream/disp32 -1784 # . . discard args -1785 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP -1786 # . clear-stream(_test-output-stream) +1767 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP +1768 # initialize input +1769 # . write(_test-input-stream, "30/imm32 # comment") +1770 # . . push args +1771 68/push "30/imm32 # comment"/imm32 +1772 68/push _test-input-stream/imm32 +1773 # . . call +1774 e8/call write/disp32 +1775 # . . discard args +1776 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP +1777 # convert-data(_test-input-stream, _test-output-buffered-file) +1778 # . . push args +1779 68/push _test-output-buffered-file/imm32 +1780 68/push _test-input-stream/imm32 +1781 # . . call +1782 e8/call convert-data/disp32 +1783 # . . discard args +1784 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP +1785 # check output +1786 # . flush(_test-output-buffered-file) 1787 # . . push args -1788 68/push _test-output-stream/imm32 +1788 68/push _test-output-buffered-file/imm32 1789 # . . call -1790 e8/call clear-stream/disp32 +1790 e8/call flush/disp32 1791 # . . discard args 1792 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP -1793 # . clear-stream(_test-output-buffered-file+4) -1794 # . . push args -1795 b8/copy-to-EAX _test-output-buffered-file/imm32 -1796 05/add-to-EAX 4/imm32 -1797 50/push-EAX -1798 # . . call -1799 e8/call clear-stream/disp32 -1800 # . . discard args -1801 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP -1802 # initialize input -1803 # . write(_test-input-stream, "30 abcd/o 42e1/imm32") -1804 # . . push args -1805 68/push "30 abcd/o 42e1/imm32"/imm32 -1806 68/push _test-input-stream/imm32 -1807 # . . call -1808 e8/call write/disp32 -1809 # . . discard args -1810 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP -1811 # convert-data(_test-input-stream, _test-output-buffered-file) -1812 # . . push args -1813 68/push _test-output-buffered-file/imm32 -1814 68/push _test-input-stream/imm32 -1815 # . . call -1816 e8/call convert-data/disp32 -1817 # . . discard args -1818 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP -1819 # check output -1820 # . flush(_test-output-buffered-file) -1821 # . . push args -1822 68/push _test-output-buffered-file/imm32 -1823 # . . call -1824 e8/call flush/disp32 -1825 # . . discard args -1826 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP -1827 +-- 34 lines: #? # dump output --------------------------------------------------------------------------------------------------------------------------- -1861 # . check-stream-equal(_test-output-stream, "30 abcd/o 42 e1 00 00 ", msg) -1862 # . . push args -1863 68/push "F - test-convert-data-multiple-words"/imm32 -1864 68/push "30 abcd/o e1 42 00 00 "/imm32 -1865 68/push _test-output-stream/imm32 -1866 # . . call -1867 e8/call check-stream-equal/disp32 -1868 # . . discard args -1869 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP -1870 # . epilog -1871 89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . . # copy EBP to ESP -1872 5d/pop-to-EBP -1873 c3/return -1874 -1875 test-convert-data-trailing-comment: -1876 # Trailing comments in data segment get appropriately ignored. -1877 # . prolog -1878 55/push-EBP -1879 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP -1880 # setup -1881 # . clear-stream(_test-input-stream) -1882 # . . push args -1883 68/push _test-input-stream/imm32 -1884 # . . call -1885 e8/call clear-stream/disp32 -1886 # . . discard args -1887 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP -1888 # . clear-stream(_test-output-stream) -1889 # . . push args -1890 68/push _test-output-stream/imm32 -1891 # . . call -1892 e8/call clear-stream/disp32 -1893 # . . discard args -1894 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP -1895 # . clear-stream(_test-output-buffered-file+4) -1896 # . . push args -1897 b8/copy-to-EAX _test-output-buffered-file/imm32 -1898 05/add-to-EAX 4/imm32 -1899 50/push-EAX -1900 # . . call -1901 e8/call clear-stream/disp32 -1902 # . . discard args -1903 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP -1904 # initialize input -1905 # . write(_test-input-stream, "30/imm32 # comment") -1906 # . . push args -1907 68/push "30/imm32 # comment"/imm32 -1908 68/push _test-input-stream/imm32 -1909 # . . call -1910 e8/call write/disp32 -1911 # . . discard args -1912 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP -1913 # convert-data(_test-input-stream, _test-output-buffered-file) -1914 # . . push args -1915 68/push _test-output-buffered-file/imm32 -1916 68/push _test-input-stream/imm32 -1917 # . . call -1918 e8/call convert-data/disp32 -1919 # . . discard args -1920 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP -1921 # check output -1922 # . flush(_test-output-buffered-file) -1923 # . . push args -1924 68/push _test-output-buffered-file/imm32 -1925 # . . call -1926 e8/call flush/disp32 -1927 # . . discard args -1928 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP -1929 +-- 34 lines: #? # dump output --------------------------------------------------------------------------------------------------------------------------- -1963 # . check-stream-equal(_test-output-stream, "30 00 00 00 # comment", msg) -1964 # . . push args -1965 68/push "F - test-convert-data-trailing-comment"/imm32 -1966 68/push "30 00 00 00 # comment"/imm32 -1967 68/push _test-output-stream/imm32 -1968 # . . call -1969 e8/call check-stream-equal/disp32 -1970 # . . discard args -1971 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP -1972 # . epilog -1973 89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . . # copy EBP to ESP -1974 5d/pop-to-EBP -1975 c3/return -1976 -1977 # pack an instruction, following the C++ version -1978 # -1979 # zero error handling at the moment (continuing to rely on the C++ version for that): -1980 # missing fields are always 0-filled -1981 # bytes never mentioned are silently dropped; if you don't provide /mod, /rm32 or /r32 you don't get a 0 ModR/M byte. You get *no* ModR/M byte. -1982 # may pick up any of duplicate operands in an instruction -1983 # silently drop extraneous operands -1984 # unceremoniously abort on non-numeric operands except disp or imm -1985 # opcodes must be lowercase and zero padded -1986 # opcodes with misleading operand metadata may get duplicated as operands as well. don't rely on this. -1987 convert-instruction: # line : (address stream byte), out : (address buffered-file) -> <void> -1988 # pseudocode: -1989 # # some early exits -1990 # var word-slice = next-word(line) -1991 # if slice-empty?(word-slice) -1992 # write-stream-data(out, line) -1993 # return -1994 # if slice-starts-with?(word-slice, "#") -1995 # write-stream-data(out, line) -1996 # return -1997 # if slice-ends-with?(word-slice, ":") -1998 # write-stream-data(out, line) -1999 # return -2000 # # really convert -2001 # emit-opcodes(line, out) -2002 # emit-modrm(line, out) -2003 # emit-sib(line, out) -2004 # emit-disp(line, out) -2005 # emit-imm(line, out) -2006 # emit-line-in-comment(line, out) -2007 # -2008 # . prolog -2009 55/push-EBP -2010 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP -2011 # . save registers -2012 50/push-EAX -2013 51/push-ECX -2014 52/push-EDX -2015 # var word-slice/ECX = {0, 0} -2016 68/push 0/imm32/end -2017 68/push 0/imm32/start -2018 89/copy 3/mod/direct 1/rm32/ECX . . . 4/r32/ESP . . # copy ESP to ECX -2019 # next-word(line, word-slice) -2020 # . . push args -2021 51/push-ECX -2022 ff 6/subop/push 1/mod/*+disp8 5/rm32/EBP . . . . 8/disp8 . # push *(EBP+8) -2023 # . . call -2024 e8/call next-word/disp32 -2025 # . . discard args -2026 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP -2027 $convert-instruction:check0: -2028 # if (slice-empty?(word-slice)) break -2029 # . EAX = slice-empty?(word-slice) -2030 # . . push args -2031 51/push-ECX -2032 # . . call -2033 e8/call slice-empty?/disp32 -2034 # . . discard args -2035 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP -2036 # . if (EAX != 0) pass through -2037 3d/compare-EAX-and 0/imm32 -2038 75/jump-if-not-equal $convert-instruction:pass-through/disp8 -2039 $convert-instruction:check1: -2040 # if (slice-starts-with?(word-slice, "#")) write-stream-data(out, line) -2041 # . start/EDX = word-slice->start -2042 8b/copy 0/mod/indirect 1/rm32/ECX . . . 2/r32/EDX . . # copy *ECX to EDX -2043 # . c/EAX = *start -2044 31/xor 3/mod/direct 0/rm32/EAX . . . 0/r32/EAX . . # clear EAX -2045 8a/copy-byte 0/mod/indirect 2/rm32/EDX . . . 0/r32/AL . . # copy byte at *EDX to AL -2046 # . if (EAX == '#') pass through -2047 3d/compare-EAX-and 0x23/imm32/hash -2048 74/jump-if-equal $convert-instruction:pass-through/disp8 -2049 $convert-instruction:check2: -2050 # if (slice-ends-with?(word-slice, ":")) write-stream-data(out, line) -2051 # . end/EDX = word-slice->end -2052 8b/copy 1/mod/*+disp8 1/rm32/ECX . . . 2/r32/EDX 4/disp8 . # copy *(ECX+4) to EDX -2053 # . c/EAX = *(end-1) -2054 31/xor 3/mod/direct 0/rm32/EAX . . . 0/r32/EAX . . # clear EAX -2055 8a/copy-byte 1/mod/*+disp8 2/rm32/EDX . . . 0/r32/AL -1/disp8 . # copy byte at *ECX to AL -2056 # . if (EAX == ':') pass through -2057 3d/compare-EAX-and 0x3a/imm32/colon -2058 75/jump-if-not-equal $convert-instruction:really-convert/disp8 -2059 $convert-instruction:pass-through: -2060 # write-stream-data(out, line) -2061 # . . push args -2062 ff 6/subop/push 1/mod/*+disp8 5/rm32/EBP . . . . 8/disp8 . # push *(EBP+8) -2063 ff 6/subop/push 1/mod/*+disp8 5/rm32/EBP . . . . 0xc/disp8 . # push *(EBP+12) -2064 # . . call -2065 e8/call write-stream-data/disp32 -2066 # . . discard args -2067 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP -2068 # return -2069 eb/jump $convert-instruction:end/disp8 -2070 $convert-instruction:really-convert: -2071 # emit-opcodes(line, out) -2072 # . . push args -2073 ff 6/subop/push 1/mod/*+disp8 5/rm32/EBP . . . . 0xc/disp8 . # push *(EBP+8) -2074 ff 6/subop/push 1/mod/*+disp8 5/rm32/EBP . . . . 8/disp8 . # push *(EBP+8) -2075 # . . call -2076 e8/call emit-opcodes/disp32 -2077 # . . discard args -2078 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP -2079 # emit-modrm(line, out) -2080 # . . push args -2081 ff 6/subop/push 1/mod/*+disp8 5/rm32/EBP . . . . 0xc/disp8 . # push *(EBP+8) -2082 ff 6/subop/push 1/mod/*+disp8 5/rm32/EBP . . . . 8/disp8 . # push *(EBP+8) -2083 # . . call -2084 e8/call emit-modrm/disp32 -2085 # . . discard args -2086 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP -2087 # emit-sib(line, out) -2088 # . . push args -2089 ff 6/subop/push 1/mod/*+disp8 5/rm32/EBP . . . . 0xc/disp8 . # push *(EBP+8) -2090 ff 6/subop/push 1/mod/*+disp8 5/rm32/EBP . . . . 8/disp8 . # push *(EBP+8) -2091 # . . call -2092 e8/call emit-sib/disp32 -2093 # . . discard args -2094 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP -2095 # emit-disp(line, out) -2096 # . . push args -2097 ff 6/subop/push 1/mod/*+disp8 5/rm32/EBP . . . . 0xc/disp8 . # push *(EBP+8) -2098 ff 6/subop/push 1/mod/*+disp8 5/rm32/EBP . . . . 8/disp8 . # push *(EBP+8) -2099 # . . call -2100 e8/call emit-disp/disp32 -2101 # . . discard args -2102 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP -2103 # emit-imm(line, out) -2104 # . . push args -2105 ff 6/subop/push 1/mod/*+disp8 5/rm32/EBP . . . . 0xc/disp8 . # push *(EBP+8) -2106 ff 6/subop/push 1/mod/*+disp8 5/rm32/EBP . . . . 8/disp8 . # push *(EBP+8) -2107 # . . call -2108 e8/call emit-imm/disp32 -2109 # . . discard args -2110 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP -2111 # emit-line-in-comment(line, out) +1793 +-- 26 lines: #? # dump output --------------------------------------------------------------------------------------------------------------------------- +1819 # . check-stream-equal(_test-output-stream, "30 00 00 00 # comment", msg) +1820 # . . push args +1821 68/push "F - test-convert-data-trailing-comment"/imm32 +1822 68/push "30 00 00 00 # comment"/imm32 +1823 68/push _test-output-stream/imm32 +1824 # . . call +1825 e8/call check-stream-equal/disp32 +1826 # . . discard args +1827 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP +1828 # . epilog +1829 89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . . # copy EBP to ESP +1830 5d/pop-to-EBP +1831 c3/return +1832 +1833 # pack an instruction, following the C++ version +1834 # +1835 # zero error handling at the moment (continuing to rely on the C++ version for that): +1836 # missing fields are always 0-filled +1837 # bytes never mentioned are silently dropped; if you don't provide /mod, /rm32 or /r32 you don't get a 0 ModR/M byte. You get *no* ModR/M byte. +1838 # may pick up any of duplicate operands in an instruction +1839 # silently drop extraneous operands +1840 # unceremoniously abort on non-numeric operands except disp or imm +1841 # opcodes must be lowercase and zero padded +1842 # opcodes with misleading operand metadata may get duplicated as operands as well. don't rely on this. +1843 convert-instruction: # line : (address stream byte), out : (address buffered-file) -> <void> +1844 # pseudocode: +1845 # # some early exits +1846 # var word-slice = next-word(line) +1847 # if slice-empty?(word-slice) +1848 # write-stream-data(out, line) +1849 # return +1850 # if slice-starts-with?(word-slice, "#") +1851 # write-stream-data(out, line) +1852 # return +1853 # if slice-ends-with?(word-slice, ":") +1854 # write-stream-data(out, line) +1855 # return +1856 # # really convert +1857 # emit-opcodes(line, out) +1858 # emit-modrm(line, out) +1859 # emit-sib(line, out) +1860 # emit-disp(line, out) +1861 # emit-imm(line, out) +1862 # emit-line-in-comment(line, out) +1863 # +1864 # . prolog +1865 55/push-EBP +1866 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP +1867 # . save registers +1868 50/push-EAX +1869 51/push-ECX +1870 52/push-EDX +1871 # var word-slice/ECX = {0, 0} +1872 68/push 0/imm32/end +1873 68/push 0/imm32/start +1874 89/copy 3/mod/direct 1/rm32/ECX . . . 4/r32/ESP . . # copy ESP to ECX +1875 # next-word(line, word-slice) +1876 # . . push args +1877 51/push-ECX +1878 ff 6/subop/push 1/mod/*+disp8 5/rm32/EBP . . . . 8/disp8 . # push *(EBP+8) +1879 # . . call +1880 e8/call next-word/disp32 +1881 # . . discard args +1882 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP +1883 $convert-instruction:check0: +1884 # if (slice-empty?(word-slice)) break +1885 # . EAX = slice-empty?(word-slice) +1886 # . . push args +1887 51/push-ECX +1888 # . . call +1889 e8/call slice-empty?/disp32 +1890 # . . discard args +1891 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP +1892 # . if (EAX != 0) pass through +1893 3d/compare-EAX-and 0/imm32 +1894 75/jump-if-not-equal $convert-instruction:pass-through/disp8 +1895 $convert-instruction:check1: +1896 # if (slice-starts-with?(word-slice, "#")) write-stream-data(out, line) +1897 # . start/EDX = word-slice->start +1898 8b/copy 0/mod/indirect 1/rm32/ECX . . . 2/r32/EDX . . # copy *ECX to EDX +1899 # . c/EAX = *start +1900 31/xor 3/mod/direct 0/rm32/EAX . . . 0/r32/EAX . . # clear EAX +1901 8a/copy-byte 0/mod/indirect 2/rm32/EDX . . . 0/r32/AL . . # copy byte at *EDX to AL +1902 # . if (EAX == '#') pass through +1903 3d/compare-EAX-and 0x23/imm32/hash +1904 74/jump-if-equal $convert-instruction:pass-through/disp8 +1905 $convert-instruction:check2: +1906 # if (slice-ends-with?(word-slice, ":")) write-stream-data(out, line) +1907 # . end/EDX = word-slice->end +1908 8b/copy 1/mod/*+disp8 1/rm32/ECX . . . 2/r32/EDX 4/disp8 . # copy *(ECX+4) to EDX +1909 # . c/EAX = *(end-1) +1910 31/xor 3/mod/direct 0/rm32/EAX . . . 0/r32/EAX . . # clear EAX +1911 8a/copy-byte 1/mod/*+disp8 2/rm32/EDX . . . 0/r32/AL -1/disp8 . # copy byte at *ECX to AL +1912 # . if (EAX == ':') pass through +1913 3d/compare-EAX-and 0x3a/imm32/colon +1914 75/jump-if-not-equal $convert-instruction:really-convert/disp8 +1915 $convert-instruction:pass-through: +1916 # write-stream-data(out, line) +1917 # . . push args +1918 ff 6/subop/push 1/mod/*+disp8 5/rm32/EBP . . . . 8/disp8 . # push *(EBP+8) +1919 ff 6/subop/push 1/mod/*+disp8 5/rm32/EBP . . . . 0xc/disp8 . # push *(EBP+12) +1920 # . . call +1921 e8/call write-stream-data/disp32 +1922 # . . discard args +1923 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP +1924 # return +1925 eb/jump $convert-instruction:end/disp8 +1926 $convert-instruction:really-convert: +1927 # emit-opcodes(line, out) +1928 # . . push args +1929 ff 6/subop/push 1/mod/*+disp8 5/rm32/EBP . . . . 0xc/disp8 . # push *(EBP+12) +1930 ff 6/subop/push 1/mod/*+disp8 5/rm32/EBP . . . . 8/disp8 . # push *(EBP+8) +1931 # . . call +1932 e8/call emit-opcodes/disp32 +1933 # . . discard args +1934 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP +1935 # emit-modrm(line, out) +1936 # . . push args +1937 ff 6/subop/push 1/mod/*+disp8 5/rm32/EBP . . . . 0xc/disp8 . # push *(EBP+12) +1938 ff 6/subop/push 1/mod/*+disp8 5/rm32/EBP . . . . 8/disp8 . # push *(EBP+8) +1939 # . . call +1940 e8/call emit-modrm/disp32 +1941 # . . discard args +1942 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP +1943 # emit-sib(line, out) +1944 # . . push args +1945 ff 6/subop/push 1/mod/*+disp8 5/rm32/EBP . . . . 0xc/disp8 . # push *(EBP+12) +1946 ff 6/subop/push 1/mod/*+disp8 5/rm32/EBP . . . . 8/disp8 . # push *(EBP+8) +1947 # . . call +1948 e8/call emit-sib/disp32 +1949 # . . discard args +1950 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP +1951 # emit-disp(line, out) +1952 # . . push args +1953 ff 6/subop/push 1/mod/*+disp8 5/rm32/EBP . . . . 0xc/disp8 . # push *(EBP+12) +1954 ff 6/subop/push 1/mod/*+disp8 5/rm32/EBP . . . . 8/disp8 . # push *(EBP+8) +1955 # . . call +1956 e8/call emit-disp/disp32 +1957 # . . discard args +1958 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP +1959 # emit-imm(line, out) +1960 # . . push args +1961 ff 6/subop/push 1/mod/*+disp8 5/rm32/EBP . . . . 0xc/disp8 . # push *(EBP+12) +1962 ff 6/subop/push 1/mod/*+disp8 5/rm32/EBP . . . . 8/disp8 . # push *(EBP+8) +1963 # . . call +1964 e8/call emit-imm/disp32 +1965 # . . discard args +1966 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP +1967 # emit-line-in-comment(line, out) +1968 # . . push args +1969 ff 6/subop/push 1/mod/*+disp8 5/rm32/EBP . . . . 0xc/disp8 . # push *(EBP+12) +1970 ff 6/subop/push 1/mod/*+disp8 5/rm32/EBP . . . . 8/disp8 . # push *(EBP+8) +1971 # . . call +1972 e8/call emit-line-in-comment/disp32 +1973 # . . discard args +1974 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP +1975 $convert-instruction:end: +1976 # . restore locals +1977 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP +1978 # . restore registers +1979 5a/pop-to-EDX +1980 59/pop-to-ECX +1981 58/pop-to-EAX +1982 # . epilog +1983 89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . . # copy EBP to ESP +1984 5d/pop-to-EBP +1985 c3/return +1986 +1987 emit-opcodes: # line : (address stream byte), out : (address buffered-file) -> <void> +1988 # opcodes occupy 1-3 bytes: +1989 # xx +1990 # 0f xx +1991 # f2 xx +1992 # f3 xx +1993 # f2 0f xx +1994 # f3 0f xx +1995 # +1996 # pseudocode: +1997 # rewind-stream(line) +1998 # +1999 # var op1 = next-word(line) +2000 # if (slice-empty?(op1) || slice-starts-with?(op1, "#")) return +2001 # op1 = next-token-from-slice(op1->start, op1->end, "/") +2002 # write-slice(out, op1) +2003 # if !slice-equal?(op1, "0f") && !slice-equal?(op1, "f2") && !slice-equal?(op1, "f3") +2004 # return +2005 # +2006 # var op2 = next-word(line) +2007 # if (slice-empty?(op2) || slice-starts-with?(op2, "#")) return +2008 # op2 = next-token-from-slice(op2->start, op2->end, "/") +2009 # write-slice(out, op2) +2010 # if slice-equal?(op1, "0f") +2011 # return +2012 # if !slice-equal?(op2, "0f") +2013 # return +2014 # +2015 # var op3 = next-word(line) +2016 # if (slice-empty?(op3) || slice-starts-with?(op3, "#")) return +2017 # op3 = next-token-from-slice(op3->start, op3->end, "/") +2018 # write-slice(out, op3) +2019 # +2020 # . prolog +2021 55/push-EBP +2022 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP +2023 # . save registers +2024 50/push-EAX +2025 51/push-ECX +2026 52/push-EDX +2027 53/push-EBX +2028 # var op1/ECX = {0, 0} +2029 68/push 0/imm32/end +2030 68/push 0/imm32/start +2031 89/copy 3/mod/direct 1/rm32/ECX . . . 4/r32/ESP . . # copy ESP to ECX +2032 # var op2/EDX = {0, 0} +2033 68/push 0/imm32/end +2034 68/push 0/imm32/start +2035 89/copy 3/mod/direct 2/rm32/EDX . . . 4/r32/ESP . . # copy ESP to EDX +2036 # rewind-stream(line) +2037 # . . push args +2038 ff 6/subop/push 1/mod/*+disp8 5/rm32/EBP . . . . 8/disp8 . # push *(EBP+8) +2039 # . . call +2040 e8/call rewind-stream/disp32 +2041 # . . discard args +2042 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP +2043 $emit-opcodes:op1: +2044 # next-word(line, op1) +2045 # . . push args +2046 51/push-ECX +2047 ff 6/subop/push 1/mod/*+disp8 5/rm32/EBP . . . . 8/disp8 . # push *(EBP+8) +2048 # . . call +2049 e8/call next-word/disp32 +2050 # . . discard args +2051 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP +2052 # if (slice-empty?(op1)) return +2053 # . EAX = slice-empty?(op1) +2054 # . . push args +2055 51/push-ECX +2056 # . . call +2057 e8/call slice-empty?/disp32 +2058 # . . discard args +2059 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP +2060 # . if (EAX != 0) return +2061 3d/compare-EAX-and 0/imm32 +2062 0f 85/jump-if-not-equal $emit-opcodes:end/disp32 +2063 # if (slice-starts-with?(op1, "#")) return +2064 # . start/EBX = op1->start +2065 8b/copy 0/mod/indirect 1/rm32/ECX . . . 3/r32/EBX . . # copy *ECX to EBX +2066 # . c/EAX = *start +2067 31/xor 3/mod/direct 0/rm32/EAX . . . 0/r32/EAX . . # clear EAX +2068 8a/copy-byte 0/mod/indirect 3/rm32/EBX . . . 0/r32/AL . . # copy byte at *EBX to AL +2069 # . if (EAX == '#') return +2070 3d/compare-EAX-and 0x23/imm32/hash +2071 0f 84/jump-if-equal $emit-opcodes:end/disp32 +2072 # op1 = next-token-from-slice(op1->start, op1->end, '/') +2073 # . . push args +2074 51/push-ECX +2075 68/push 0x2f/imm32/slash +2076 ff 6/subop/push 1/mod/*+disp8 1/rm32/ECX . . . . 4/disp8 . # push *(ECX+4) +2077 ff 6/subop/push 0/mod/indirect 1/rm32/ECX . . . . . . # push *ECX +2078 # . . call +2079 e8/call next-token-from-slice/disp32 +2080 # . . discard args +2081 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0x10/imm32 # add to ESP +2082 # write-slice(out, op1) +2083 # . . push args +2084 51/push-ECX +2085 ff 6/subop/push 1/mod/*+disp8 5/rm32/EBP . . . . 0xc/disp8 . # push *(EBP+12) +2086 # . . call +2087 e8/call write-slice/disp32 +2088 # . . discard args +2089 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP +2090 # write-buffered(out, " ") +2091 # . . push args +2092 68/push " "/imm32 +2093 ff 6/subop/push 1/mod/*+disp8 5/rm32/EBP . . . . 0xc/disp8 . # push *(EBP+12) +2094 # . . call +2095 e8/call write-buffered/disp32 +2096 # . . discard args +2097 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP +2098 # if (slice-equal?(op1, "0f")) goto op2 +2099 # . EAX = slice-equal?(op1, "0f") +2100 # . . push args +2101 68/push "0f"/imm32 +2102 51/push-ECX +2103 # . . call +2104 e8/call slice-equal?/disp32 +2105 # . . discard args +2106 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP +2107 # . if (EAX != 0) goto op2 +2108 3d/compare-EAX-and 0/imm32 +2109 75/jump-if-not-equal $emit-opcodes:op2/disp8 +2110 # if (slice-equal?(op1, "f2")) goto op2 +2111 # . EAX = slice-equal?(op1, "f2") 2112 # . . push args -2113 ff 6/subop/push 1/mod/*+disp8 5/rm32/EBP . . . . 0xc/disp8 . # push *(EBP+8) -2114 ff 6/subop/push 1/mod/*+disp8 5/rm32/EBP . . . . 8/disp8 . # push *(EBP+8) +2113 68/push "f2"/imm32 +2114 51/push-ECX 2115 # . . call -2116 e8/call emit-line-in-comment/disp32 +2116 e8/call slice-equal?/disp32 2117 # . . discard args 2118 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP -2119 $convert-instruction:end: -2120 # . restore locals -2121 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP -2122 # . restore registers -2123 5a/pop-to-EDX -2124 59/pop-to-ECX -2125 58/pop-to-EAX -2126 # . epilog -2127 89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . . # copy EBP to ESP -2128 5d/pop-to-EBP -2129 c3/return -2130 -2131 emit-opcodes: # line : (address stream byte), out : (address buffered-file) -> <void> -2132 # opcodes occupy 1-3 bytes: -2133 # xx -2134 # 0f xx -2135 # f2 xx -2136 # f3 xx -2137 # f2 0f xx -2138 # f3 0f xx -2139 # -2140 # pseudocode: -2141 # rewind-stream(line) -2142 # -2143 # var op1 = next-word(line) -2144 # if (slice-empty?(op1) || slice-starts-with?(op1, "#")) return -2145 # op1 = next-token-from-slice(op1->start, op1->end, "/") -2146 # write-slice(out, op1) -2147 # if !slice-equal?(op1, "0f") && !slice-equal?(op1, "f2") && !slice-equal?(op1, "f3") -2148 # return -2149 # -2150 # var op2 = next-word(line) -2151 # if (slice-empty?(op2) || slice-starts-with?(op2, "#")) return -2152 # op2 = next-token-from-slice(op2->start, op2->end, "/") -2153 # write-slice(out, op2) -2154 # if slice-equal?(op1, "0f") -2155 # return -2156 # if !slice-equal?(op2, "0f") -2157 # return -2158 # -2159 # var op3 = next-word(line) -2160 # if (slice-empty?(op3) || slice-starts-with?(op3, "#")) return -2161 # op3 = next-token-from-slice(op3->start, op3->end, "/") -2162 # write-slice(out, op3) -2163 # -2164 # . prolog -2165 55/push-EBP -2166 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP -2167 # . save registers -2168 50/push-EAX -2169 51/push-ECX -2170 52/push-EDX -2171 53/push-EBX -2172 # var op1/ECX = {0, 0} -2173 68/push 0/imm32/end -2174 68/push 0/imm32/start -2175 89/copy 3/mod/direct 1/rm32/ECX . . . 4/r32/ESP . . # copy ESP to ECX -2176 # var op2/EDX = {0, 0} -2177 68/push 0/imm32/end -2178 68/push 0/imm32/start -2179 89/copy 3/mod/direct 2/rm32/EDX . . . 4/r32/ESP . . # copy ESP to EDX -2180 # rewind-stream(line) -2181 # . . push args -2182 ff 6/subop/push 1/mod/*+disp8 5/rm32/EBP . . . . 8/disp8 . # push *(EBP+8) -2183 # . . call -2184 e8/call rewind-stream/disp32 -2185 # . . discard args -2186 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP -2187 $emit-opcodes:op1: -2188 # next-word(line, op1) -2189 # . . push args -2190 51/push-ECX -2191 ff 6/subop/push 1/mod/*+disp8 5/rm32/EBP . . . . 8/disp8 . # push *(EBP+8) -2192 # . . call -2193 e8/call next-word/disp32 -2194 # . . discard args -2195 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP -2196 # if (slice-empty?(op1)) return -2197 # . EAX = slice-empty?(op1) -2198 # . . push args -2199 51/push-ECX -2200 # . . call -2201 e8/call slice-empty?/disp32 -2202 # . . discard args -2203 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP -2204 # . if (EAX != 0) return -2205 3d/compare-EAX-and 0/imm32 -2206 0f 85/jump-if-not-equal $emit-opcodes:end/disp32 -2207 # if (slice-starts-with?(op1, "#")) return -2208 # . start/EBX = op1->start -2209 8b/copy 0/mod/indirect 1/rm32/ECX . . . 3/r32/EBX . . # copy *ECX to EBX -2210 # . c/EAX = *start -2211 31/xor 3/mod/direct 0/rm32/EAX . . . 0/r32/EAX . . # clear EAX -2212 8a/copy-byte 0/mod/indirect 3/rm32/EBX . . . 0/r32/AL . . # copy byte at *EBX to AL -2213 # . if (EAX == '#') return -2214 3d/compare-EAX-and 0x23/imm32/hash -2215 0f 84/jump-if-equal $emit-opcodes:end/disp32 -2216 # op1 = next-token-from-slice(op1->start, op1->end, '/') +2119 # . if (EAX != 0) goto op2 +2120 3d/compare-EAX-and 0/imm32 +2121 75/jump-if-not-equal $emit-opcodes:op2/disp8 +2122 # if (slice-equal?(op1, "f3")) goto op2 +2123 # . EAX = slice-equal?(op1, "f3") +2124 # . . push args +2125 68/push "f3"/imm32 +2126 51/push-ECX +2127 # . . call +2128 e8/call slice-equal?/disp32 +2129 # . . discard args +2130 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP +2131 # . if (EAX != 0) goto op2 +2132 3d/compare-EAX-and 0/imm32 +2133 75/jump-if-not-equal $emit-opcodes:op2/disp8 +2134 # otherwise return +2135 e9/jump $emit-opcodes:end/disp32 +2136 $emit-opcodes:op2: +2137 # next-word(line, op2) +2138 # . . push args +2139 52/push-EDX +2140 ff 6/subop/push 1/mod/*+disp8 5/rm32/EBP . . . . 8/disp8 . # push *(EBP+8) +2141 # . . call +2142 e8/call next-word/disp32 +2143 # . . discard args +2144 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP +2145 # if (slice-empty?(op2)) return +2146 # . EAX = slice-empty?(op2) +2147 # . . push args +2148 52/push-EDX +2149 # . . call +2150 e8/call slice-empty?/disp32 +2151 # . . discard args +2152 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP +2153 # . if (EAX != 0) return +2154 3d/compare-EAX-and 0/imm32 +2155 0f 85/jump-if-not-equal $emit-opcodes:end/disp32 +2156 # if (slice-starts-with?(op2, "#")) return +2157 # . start/EBX = op2->start +2158 8b/copy 0/mod/indirect 2/rm32/EDX . . . 3/r32/EBX . . # copy *EDX to EBX +2159 # . c/EAX = *start +2160 31/xor 3/mod/direct 0/rm32/EAX . . . 0/r32/EAX . . # clear EAX +2161 8a/copy-byte 0/mod/indirect 3/rm32/EBX . . . 0/r32/AL . . # copy byte at *EBX to AL +2162 # . if (EAX == '#') return +2163 3d/compare-EAX-and 0x23/imm32/hash +2164 0f 84/jump-if-equal $emit-opcodes:end/disp32 +2165 # op2 = next-token-from-slice(op2->start, op2->end, '/') +2166 # . . push args +2167 52/push-EDX +2168 68/push 0x2f/imm32/slash +2169 ff 6/subop/push 1/mod/*+disp8 2/rm32/EDX . . . . 4/disp8 . # push *(EDX+4) +2170 ff 6/subop/push 0/mod/indirect 2/rm32/EDX . . . . . . # push *EDX +2171 # . . call +2172 e8/call next-token-from-slice/disp32 +2173 # . . discard args +2174 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0x10/imm32 # add to ESP +2175 # write-slice(out, op2) +2176 # . . push args +2177 52/push-EDX +2178 ff 6/subop/push 1/mod/*+disp8 5/rm32/EBP . . . . 0xc/disp8 . # push *(EBP+12) +2179 # . . call +2180 e8/call write-slice/disp32 +2181 # . . discard args +2182 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP +2183 # write-buffered(out, " ") +2184 # . . push args +2185 68/push " "/imm32 +2186 ff 6/subop/push 1/mod/*+disp8 5/rm32/EBP . . . . 0xc/disp8 . # push *(EBP+12) +2187 # . . call +2188 e8/call write-buffered/disp32 +2189 # . . discard args +2190 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP +2191 # if (slice-equal?(op1, "0f")) return +2192 # . EAX = slice-equal?(op1, "0f") +2193 # . . push args +2194 68/push "0f"/imm32 +2195 51/push-ECX +2196 # . . call +2197 e8/call slice-equal?/disp32 +2198 # . . discard args +2199 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP +2200 # . if (EAX != 0) return +2201 3d/compare-EAX-and 0/imm32 +2202 0f 85/jump-if-not-equal $emit-opcodes:end/disp32 +2203 # if (!slice-equal?(op2, "0f")) return +2204 # . EAX = slice-equal?(op2, "0f") +2205 # . . push args +2206 68/push "0f"/imm32 +2207 52/push-EDX +2208 # . . call +2209 e8/call slice-equal?/disp32 +2210 # . . discard args +2211 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP +2212 # . if (EAX == 0) return +2213 3d/compare-EAX-and 0/imm32 +2214 0f 84/jump-if-equal $emit-opcodes:end/disp32 +2215 $emit-opcodes:op3: +2216 # next-word(line, op3) # reuse op2/EDX 2217 # . . push args -2218 51/push-ECX -2219 68/push 0x2f/imm32/slash -2220 ff 6/subop/push 1/mod/*+disp8 1/rm32/ECX . . . . 4/disp8 . # push *(ECX+4) -2221 ff 6/subop/push 0/mod/indirect 1/rm32/ECX . . . . . . # push *ECX -2222 # . . call -2223 e8/call next-token-from-slice/disp32 -2224 # . . discard args -2225 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0x10/imm32 # add to ESP -2226 # write-slice(out, op1) -2227 # . . push args -2228 51/push-ECX -2229 ff 6/subop/push 1/mod/*+disp8 5/rm32/EBP . . . . 0xc/disp8 . # push *(EBP+12) -2230 # . . call -2231 e8/call write-slice/disp32 -2232 # . . discard args -2233 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP -2234 # write-buffered(out, " ") -2235 # . . push args -2236 68/push " "/imm32 -2237 ff 6/subop/push 1/mod/*+disp8 5/rm32/EBP . . . . 0xc/disp8 . # push *(EBP+12) -2238 # . . call -2239 e8/call write-buffered/disp32 -2240 # . . discard args -2241 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP -2242 # if (slice-equal?(op1, "0f")) goto op2 -2243 # . EAX = slice-equal?(op1, "0f") -2244 # . . push args -2245 68/push "0f"/imm32 -2246 51/push-ECX -2247 # . . call -2248 e8/call slice-equal?/disp32 -2249 # . . discard args -2250 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP -2251 # . if (EAX != 0) goto op2 -2252 3d/compare-EAX-and 0/imm32 -2253 75/jump-if-not-equal $emit-opcodes:op2/disp8 -2254 # if (slice-equal?(op1, "f2")) goto op2 -2255 # . EAX = slice-equal?(op1, "f2") -2256 # . . push args -2257 68/push "f2"/imm32 -2258 51/push-ECX -2259 # . . call -2260 e8/call slice-equal?/disp32 -2261 # . . discard args -2262 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP -2263 # . if (EAX != 0) goto op2 -2264 3d/compare-EAX-and 0/imm32 -2265 75/jump-if-not-equal $emit-opcodes:op2/disp8 -2266 # if (slice-equal?(op1, "f3")) goto op2 -2267 # . EAX = slice-equal?(op1, "f3") -2268 # . . push args -2269 68/push "f3"/imm32 -2270 51/push-ECX -2271 # . . call -2272 e8/call slice-equal?/disp32 -2273 # . . discard args -2274 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP -2275 # . if (EAX != 0) goto op2 -2276 3d/compare-EAX-and 0/imm32 -2277 75/jump-if-not-equal $emit-opcodes:op2/disp8 -2278 # otherwise return -2279 e9/jump $emit-opcodes:end/disp32 -2280 $emit-opcodes:op2: -2281 # next-word(line, op2) -2282 # . . push args -2283 52/push-EDX -2284 ff 6/subop/push 1/mod/*+disp8 5/rm32/EBP . . . . 8/disp8 . # push *(EBP+8) -2285 # . . call -2286 e8/call next-word/disp32 -2287 # . . discard args -2288 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP -2289 # if (slice-empty?(op2)) return -2290 # . EAX = slice-empty?(op2) -2291 # . . push args -2292 52/push-EDX -2293 # . . call -2294 e8/call slice-empty?/disp32 -2295 # . . discard args -2296 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP -2297 # . if (EAX != 0) return -2298 3d/compare-EAX-and 0/imm32 -2299 0f 85/jump-if-not-equal $emit-opcodes:end/disp32 -2300 # if (slice-starts-with?(op2, "#")) return -2301 # . start/EBX = op2->start -2302 8b/copy 0/mod/indirect 2/rm32/EDX . . . 3/r32/EBX . . # copy *EDX to EBX -2303 # . c/EAX = *start -2304 31/xor 3/mod/direct 0/rm32/EAX . . . 0/r32/EAX . . # clear EAX -2305 8a/copy-byte 0/mod/indirect 3/rm32/EBX . . . 0/r32/AL . . # copy byte at *EBX to AL -2306 # . if (EAX == '#') return -2307 3d/compare-EAX-and 0x23/imm32/hash -2308 0f 84/jump-if-equal $emit-opcodes:end/disp32 -2309 # op2 = next-token-from-slice(op2->start, op2->end, '/') -2310 # . . push args -2311 52/push-EDX -2312 68/push 0x2f/imm32/slash -2313 ff 6/subop/push 1/mod/*+disp8 2/rm32/EDX . . . . 4/disp8 . # push *(EDX+4) -2314 ff 6/subop/push 0/mod/indirect 2/rm32/EDX . . . . . . # push *EDX -2315 # . . call -2316 e8/call next-token-from-slice/disp32 -2317 # . . discard args -2318 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0x10/imm32 # add to ESP -2319 # write-slice(out, op2) -2320 # . . push args -2321 52/push-EDX -2322 ff 6/subop/push 1/mod/*+disp8 5/rm32/EBP . . . . 0xc/disp8 . # push *(EBP+12) -2323 # . . call -2324 e8/call write-slice/disp32 -2325 # . . discard args -2326 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP -2327 # write-buffered(out, " ") -2328 # . . push args -2329 68/push " "/imm32 -2330 ff 6/subop/push 1/mod/*+disp8 5/rm32/EBP . . . . 0xc/disp8 . # push *(EBP+12) -2331 # . . call -2332 e8/call write-buffered/disp32 -2333 # . . discard args -2334 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP -2335 # if (slice-equal?(op1, "0f")) return -2336 # . EAX = slice-equal?(op1, "0f") -2337 # . . push args -2338 68/push "0f"/imm32 -2339 51/push-ECX -2340 # . . call -2341 e8/call slice-equal?/disp32 -2342 # . . discard args -2343 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP -2344 # . if (EAX != 0) return -2345 3d/compare-EAX-and 0/imm32 -2346 0f 85/jump-if-not-equal $emit-opcodes:end/disp32 -2347 # if (!slice-equal?(op2, "0f")) return -2348 # . EAX = slice-equal?(op2, "0f") -2349 # . . push args -2350 68/push "0f"/imm32 -2351 52/push-EDX -2352 # . . call -2353 e8/call slice-equal?/disp32 -2354 # . . discard args -2355 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP -2356 # . if (EAX == 0) return -2357 3d/compare-EAX-and 0/imm32 -2358 0f 84/jump-if-equal $emit-opcodes:end/disp32 -2359 $emit-opcodes:op3: -2360 # next-word(line, op3) # reuse op2/EDX -2361 # . . push args -2362 52/push-EDX -2363 ff 6/subop/push 1/mod/*+disp8 5/rm32/EBP . . . . 8/disp8 . # push *(EBP+8) -2364 # . . call -2365 e8/call next-word/disp32 -2366 # . . discard args -2367 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP -2368 # if (slice-empty?(op3)) return -2369 # . EAX = slice-empty?(op3) -2370 # . . push args -2371 52/push-EDX -2372 # . . call -2373 e8/call slice-empty?/disp32 -2374 # . . discard args -2375 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP -2376 # . if (EAX != 0) return -2377 3d/compare-EAX-and 0/imm32 -2378 0f 85/jump-if-not-equal $emit-opcodes:end/disp32 -2379 # if (slice-starts-with?(op3, "#")) return -2380 # . start/EBX = op2->start -2381 8b/copy 0/mod/indirect 2/rm32/EDX . . . 3/r32/EBX . . # copy *EDX to EBX -2382 # . c/EAX = *start -2383 31/xor 3/mod/direct 0/rm32/EAX . . . 0/r32/EAX . . # clear EAX -2384 8a/copy-byte 0/mod/indirect 3/rm32/EBX . . . 0/r32/AL . . # copy byte at *EBX to AL -2385 # . if (EAX == '#') return -2386 3d/compare-EAX-and 0x23/imm32/hash -2387 0f 84/jump-if-equal $emit-opcodes:end/disp32 -2388 # op3 = next-token-from-slice(op3->start, op3->end, '/') -2389 # . . push args -2390 52/push-EDX -2391 68/push 0x2f/imm32/slash -2392 ff 6/subop/push 1/mod/*+disp8 2/rm32/EDX . . . . 4/disp8 . # push *(EDX+4) -2393 ff 6/subop/push 0/mod/indirect 2/rm32/EDX . . . . . . # push *EDX -2394 # . . call -2395 e8/call next-token-from-slice/disp32 -2396 # . . discard args -2397 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0x10/imm32 # add to ESP -2398 # write-slice(out, op3) -2399 # . . push args -2400 52/push-EDX -2401 ff 6/subop/push 1/mod/*+disp8 5/rm32/EBP . . . . 0xc/disp8 . # push *(EBP+12) -2402 # . . call -2403 e8/call write-slice/disp32 -2404 # . . discard args -2405 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP -2406 # write-buffered(out, " ") -2407 # . . push args -2408 68/push " "/imm32 -2409 ff 6/subop/push 1/mod/*+disp8 5/rm32/EBP . . . . 0xc/disp8 . # push *(EBP+12) -2410 # . . call -2411 e8/call write-buffered/disp32 -2412 # . . discard args -2413 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP -2414 $emit-opcodes:end: -2415 # . restore locals -2416 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0x10/imm32 # add to ESP -2417 # . restore registers -2418 5b/pop-to-EBX -2419 5a/pop-to-EDX -2420 59/pop-to-ECX -2421 58/pop-to-EAX -2422 # . epilog -2423 89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . . # copy EBP to ESP -2424 5d/pop-to-EBP -2425 c3/return -2426 -2427 emit-modrm: # line : (address stream byte), out : (address buffered-file) -> <void> -2428 # pseudocode: -2429 # rewind-stream(line) -2430 # var has-modrm? = false, mod = 0, rm32 = 0, r32 = 0 -2431 # var word-slice = {0, 0} -2432 # while true -2433 # word-slice = next-word(line) -2434 # if (slice-empty?(word-slice)) break -2435 # if (slice-starts-with?(word-slice, "#")) break -2436 # if (has-metadata?(word-slice, "mod")) -2437 # mod = parse-hex-int(next-token-from-slice(word-slice, "/")) -2438 # has-modrm? = true -2439 # else if (has-metadata?(word-slice, "rm32")) -2440 # rm32 = parse-hex-int(next-token-from-slice(word-slice, "/")) -2441 # has-modrm? = true -2442 # else if (has-metadata?(word-slice, "r32") or has-metadata?(word-slice, "subop")) -2443 # r32 = parse-hex-int(next-token-from-slice(word-slice, "/")) -2444 # has-modrm? = true -2445 # if has-modrm? -2446 # var modrm = mod & 0b11 -2447 # modrm <<= 2 -2448 # modrm |= r32 & 0b111 -2449 # modrm <<= 3 -2450 # modrm |= rm32 & 0b111 -2451 # emit-hex(out, modrm, 1) -2452 # -2453 # . prolog -2454 55/push-EBP -2455 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP -2456 # . save registers -2457 50/push-EAX +2218 52/push-EDX +2219 ff 6/subop/push 1/mod/*+disp8 5/rm32/EBP . . . . 8/disp8 . # push *(EBP+8) +2220 # . . call +2221 e8/call next-word/disp32 +2222 # . . discard args +2223 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP +2224 # if (slice-empty?(op3)) return +2225 # . EAX = slice-empty?(op3) +2226 # . . push args +2227 52/push-EDX +2228 # . . call +2229 e8/call slice-empty?/disp32 +2230 # . . discard args +2231 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP +2232 # . if (EAX != 0) return +2233 3d/compare-EAX-and 0/imm32 +2234 0f 85/jump-if-not-equal $emit-opcodes:end/disp32 +2235 # if (slice-starts-with?(op3, "#")) return +2236 # . start/EBX = op2->start +2237 8b/copy 0/mod/indirect 2/rm32/EDX . . . 3/r32/EBX . . # copy *EDX to EBX +2238 # . c/EAX = *start +2239 31/xor 3/mod/direct 0/rm32/EAX . . . 0/r32/EAX . . # clear EAX +2240 8a/copy-byte 0/mod/indirect 3/rm32/EBX . . . 0/r32/AL . . # copy byte at *EBX to AL +2241 # . if (EAX == '#') return +2242 3d/compare-EAX-and 0x23/imm32/hash +2243 0f 84/jump-if-equal $emit-opcodes:end/disp32 +2244 # op3 = next-token-from-slice(op3->start, op3->end, '/') +2245 # . . push args +2246 52/push-EDX +2247 68/push 0x2f/imm32/slash +2248 ff 6/subop/push 1/mod/*+disp8 2/rm32/EDX . . . . 4/disp8 . # push *(EDX+4) +2249 ff 6/subop/push 0/mod/indirect 2/rm32/EDX . . . . . . # push *EDX +2250 # . . call +2251 e8/call next-token-from-slice/disp32 +2252 # . . discard args +2253 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0x10/imm32 # add to ESP +2254 # write-slice(out, op3) +2255 # . . push args +2256 52/push-EDX +2257 ff 6/subop/push 1/mod/*+disp8 5/rm32/EBP . . . . 0xc/disp8 . # push *(EBP+12) +2258 # . . call +2259 e8/call write-slice/disp32 +2260 # . . discard args +2261 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP +2262 # write-buffered(out, " ") +2263 # . . push args +2264 68/push " "/imm32 +2265 ff 6/subop/push 1/mod/*+disp8 5/rm32/EBP . . . . 0xc/disp8 . # push *(EBP+12) +2266 # . . call +2267 e8/call write-buffered/disp32 +2268 # . . discard args +2269 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP +2270 $emit-opcodes:end: +2271 # . restore locals +2272 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0x10/imm32 # add to ESP +2273 # . restore registers +2274 5b/pop-to-EBX +2275 5a/pop-to-EDX +2276 59/pop-to-ECX +2277 58/pop-to-EAX +2278 # . epilog +2279 89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . . # copy EBP to ESP +2280 5d/pop-to-EBP +2281 c3/return +2282 +2283 emit-modrm: # line : (address stream byte), out : (address buffered-file) -> <void> +2284 # pseudocode: +2285 # rewind-stream(line) +2286 # var has-modrm? = false, mod = 0, rm32 = 0, r32 = 0 +2287 # var word-slice = {0, 0} +2288 # while true +2289 # word-slice = next-word(line) +2290 # if (slice-empty?(word-slice)) break +2291 # if (slice-starts-with?(word-slice, "#")) break +2292 # if (has-metadata?(word-slice, "mod")) +2293 # mod = parse-hex-int(next-token-from-slice(word-slice, "/")) +2294 # has-modrm? = true +2295 # else if (has-metadata?(word-slice, "rm32")) +2296 # rm32 = parse-hex-int(next-token-from-slice(word-slice, "/")) +2297 # has-modrm? = true +2298 # else if (has-metadata?(word-slice, "r32") or has-metadata?(word-slice, "subop")) +2299 # r32 = parse-hex-int(next-token-from-slice(word-slice, "/")) +2300 # has-modrm? = true +2301 # if has-modrm? +2302 # var modrm = mod & 0b11 +2303 # modrm <<= 2 +2304 # modrm |= r32 & 0b111 +2305 # modrm <<= 3 +2306 # modrm |= rm32 & 0b111 +2307 # emit-hex(out, modrm, 1) +2308 # +2309 # . prolog +2310 55/push-EBP +2311 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP +2312 # . save registers +2313 50/push-EAX +2314 51/push-ECX +2315 52/push-EDX +2316 53/push-EBX +2317 56/push-ESI +2318 57/push-EDI +2319 # var word-slice/ECX = {0, 0} +2320 68/push 0/imm32/end +2321 68/push 0/imm32/start +2322 89/copy 3/mod/direct 1/rm32/ECX . . . 4/r32/ESP . . # copy ESP to ECX +2323 # var has-modrm?/EDX = false +2324 31/xor 3/mod/direct 2/rm32/EDX . . . 2/r32/EDX . . # clear EDX +2325 # var mod/EBX = 0 +2326 31/xor 3/mod/direct 3/rm32/EBX . . . 3/r32/EBX . . # clear EBX +2327 # var rm32/ESI = 0 +2328 31/xor 3/mod/direct 6/rm32/ESI . . . 6/r32/ESI . . # clear ESI +2329 # var r32/EDI = 0 +2330 31/xor 3/mod/direct 7/rm32/EDI . . . 7/r32/EDI . . # clear EDI +2331 # rewind-stream(line) +2332 # . . push args +2333 ff 6/subop/push 1/mod/*+disp8 5/rm32/EBP . . . . 8/disp8 . # push *(EBP+8) +2334 # . . call +2335 e8/call rewind-stream/disp32 +2336 # . . discard args +2337 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP +2338 $emit-modrm:loop: +2339 +-- 26 lines: #? # dump line ----------------------------------------------------------------------------------------------------------------------------- +2365 # next-word(line, word-slice) +2366 # . . push args +2367 51/push-ECX +2368 ff 6/subop/push 1/mod/*+disp8 5/rm32/EBP . . . . 8/disp8 . # push *(EBP+8) +2369 # . . call +2370 e8/call next-word/disp32 +2371 # . . discard args +2372 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP +2373 +-- 42 lines: #? # dump word-slice ----------------------------------------------------------------------------------------------------------------------- +2415 $emit-modrm:check0: +2416 # if (slice-empty?(word-slice)) break +2417 # . EAX = slice-empty?(word-slice) +2418 # . . push args +2419 51/push-ECX +2420 # . . call +2421 e8/call slice-empty?/disp32 +2422 # . . discard args +2423 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP +2424 # . if (EAX != 0) pass through +2425 3d/compare-EAX-and 0/imm32 +2426 0f 85/jump-if-not-equal $emit-modrm:break/disp32 +2427 $emit-modrm:check1: +2428 # if (slice-starts-with?(word-slice, "#")) break +2429 # . spill EDX +2430 52/push-EDX +2431 # . start/EDX = word-slice->start +2432 8b/copy 0/mod/indirect 1/rm32/ECX . . . 2/r32/EDX . . # copy *ECX to EDX +2433 # . c/EAX = *start +2434 31/xor 3/mod/direct 0/rm32/EAX . . . 0/r32/EAX . . # clear EAX +2435 8a/copy-byte 0/mod/indirect 2/rm32/EDX . . . 0/r32/AL . . # copy byte at *EDX to AL +2436 # . restore EDX +2437 5a/pop-to-EDX +2438 # . if (EAX == '#') pass through +2439 3d/compare-EAX-and 0x23/imm32/hash +2440 0f 84/jump-if-equal $emit-modrm:break/disp32 +2441 $emit-modrm:check-for-mod: +2442 # if (has-metadata?(word-slice, "mod")) +2443 # . EAX = has-metadata?(ECX, "mod") +2444 # . . push args +2445 68/push "mod"/imm32 +2446 51/push-ECX +2447 # . . call +2448 e8/call has-metadata?/disp32 +2449 # . . discard args +2450 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP +2451 # . if (EAX == 0) goto next check +2452 3d/compare-EAX-and 0/imm32 +2453 74/jump-if-equal $emit-modrm:check-for-rm32/disp8 +2454 $emit-modrm:mod: +2455 # mod = parse-hex-int(next-token-from-slice(word-slice->start, word-slice->end, '/')) +2456 # . EAX = parse-datum-of-word(word-slice) +2457 # . . push args 2458 51/push-ECX -2459 52/push-EDX -2460 53/push-EBX -2461 56/push-ESI -2462 57/push-EDI -2463 # var word-slice/ECX = {0, 0} -2464 68/push 0/imm32/end -2465 68/push 0/imm32/start -2466 89/copy 3/mod/direct 1/rm32/ECX . . . 4/r32/ESP . . # copy ESP to ECX -2467 # var has-modrm?/EDX = false -2468 31/xor 3/mod/direct 2/rm32/EDX . . . 2/r32/EDX . . # clear EDX -2469 # var mod/EBX = 0 -2470 31/xor 3/mod/direct 3/rm32/EBX . . . 3/r32/EBX . . # clear EBX -2471 # var rm32/ESI = 0 -2472 31/xor 3/mod/direct 6/rm32/ESI . . . 6/r32/ESI . . # clear ESI -2473 # var r32/EDI = 0 -2474 31/xor 3/mod/direct 7/rm32/EDI . . . 7/r32/EDI . . # clear EDI -2475 # rewind-stream(line) -2476 # . . push args -2477 ff 6/subop/push 1/mod/*+disp8 5/rm32/EBP . . . . 8/disp8 . # push *(EBP+8) -2478 # . . call -2479 e8/call rewind-stream/disp32 -2480 # . . discard args -2481 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP -2482 $emit-modrm:loop: -2483 +-- 34 lines: #? # dump line ----------------------------------------------------------------------------------------------------------------------------- -2517 # next-word(line, word-slice) -2518 # . . push args -2519 51/push-ECX -2520 ff 6/subop/push 1/mod/*+disp8 5/rm32/EBP . . . . 8/disp8 . # push *(EBP+8) -2521 # . . call -2522 e8/call next-word/disp32 -2523 # . . discard args -2524 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP -2525 +-- 50 lines: #? # dump word-slice ----------------------------------------------------------------------------------------------------------------------- -2575 $emit-modrm:check0: -2576 # if (slice-empty?(word-slice)) break -2577 # . EAX = slice-empty?(word-slice) -2578 # . . push args -2579 51/push-ECX -2580 # . . call -2581 e8/call slice-empty?/disp32 -2582 # . . discard args -2583 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP -2584 # . if (EAX != 0) pass through -2585 3d/compare-EAX-and 0/imm32 -2586 0f 85/jump-if-not-equal $emit-modrm:break/disp32 -2587 $emit-modrm:check1: -2588 # if (slice-starts-with?(word-slice, "#")) break -2589 # . spill EDX -2590 52/push-EDX -2591 # . start/EDX = word-slice->start -2592 8b/copy 0/mod/indirect 1/rm32/ECX . . . 2/r32/EDX . . # copy *ECX to EDX -2593 # . c/EAX = *start -2594 31/xor 3/mod/direct 0/rm32/EAX . . . 0/r32/EAX . . # clear EAX -2595 8a/copy-byte 0/mod/indirect 2/rm32/EDX . . . 0/r32/AL . . # copy byte at *EDX to AL -2596 # . restore EDX -2597 5a/pop-to-EDX -2598 # . if (EAX == '#') pass through -2599 3d/compare-EAX-and 0x23/imm32/hash -2600 0f 84/jump-if-equal $emit-modrm:break/disp32 -2601 $emit-modrm:check-for-mod: -2602 # if (has-metadata?(word-slice, "mod")) -2603 # . EAX = has-metadata?(ECX, "mod") -2604 # . . push args -2605 68/push "mod"/imm32 -2606 51/push-ECX -2607 # . . call -2608 e8/call has-metadata?/disp32 -2609 # . . discard args -2610 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP -2611 # . if (EAX == 0) goto next check -2612 3d/compare-EAX-and 0/imm32 -2613 74/jump-if-equal $emit-modrm:check-for-rm32/disp8 -2614 $emit-modrm:mod: -2615 # mod = parse-hex-int(next-token-from-slice(word-slice->start, word-slice->end, '/')) -2616 # . EAX = parse-datum-of-word(word-slice) -2617 # . . push args -2618 51/push-ECX -2619 # . . call -2620 e8/call parse-datum-of-word/disp32 -2621 # . . discard args -2622 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP -2623 # . mod = EAX -2624 89/copy 3/mod/direct 3/rm32/EBX . . . 0/r32/EAX . . # copy EAX to EBX -2625 # has-modrm? = true -2626 ba/copy-to-EDX 1/imm32/true -2627 # continue -2628 e9/jump $emit-modrm:loop/disp32 -2629 $emit-modrm:check-for-rm32: -2630 # if (has-metadata?(word-slice, "rm32")) -2631 # . EAX = has-metadata?(ECX, "rm32") -2632 # . . push args -2633 68/push "rm32"/imm32 -2634 51/push-ECX -2635 # . . call -2636 e8/call has-metadata?/disp32 -2637 # . . discard args -2638 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP -2639 # . if (EAX == 0) goto next check -2640 3d/compare-EAX-and 0/imm32 -2641 74/jump-if-equal $emit-modrm:check-for-r32/disp8 -2642 $emit-modrm:rm32: -2643 # rm32 = parse-hex-int(next-token-from-slice(word-slice->start, word-slice->end, '/')) -2644 # . EAX = parse-datum-of-word(word-slice) -2645 # . . push args -2646 51/push-ECX -2647 # . . call -2648 e8/call parse-datum-of-word/disp32 -2649 # . . discard args -2650 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP -2651 # . rm32 = EAX -2652 89/copy 3/mod/direct 6/rm32/ESI . . . 0/r32/EAX . . # copy EAX to ESI -2653 # has-modrm? = true -2654 ba/copy-to-EDX 1/imm32/true -2655 # continue -2656 e9/jump $emit-modrm:loop/disp32 -2657 $emit-modrm:check-for-r32: -2658 # if (has-metadata?(word-slice, "r32")) -2659 # . EAX = has-metadata?(ECX, "r32") -2660 # . . push args -2661 68/push "r32"/imm32 -2662 51/push-ECX -2663 # . . call -2664 e8/call has-metadata?/disp32 -2665 # . . discard args -2666 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP -2667 # . if (EAX == 0) goto next check -2668 3d/compare-EAX-and 0/imm32 -2669 74/jump-if-equal $emit-modrm:check-for-subop/disp8 -2670 $emit-modrm:r32: -2671 # r32 = parse-hex-int(next-token-from-slice(word-slice->start, word-slice->end, '/')) -2672 # . EAX = parse-datum-of-word(word-slice) -2673 # . . push args -2674 51/push-ECX -2675 # . . call -2676 e8/call parse-datum-of-word/disp32 -2677 # . . discard args -2678 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP -2679 # . r32 = EAX -2680 89/copy 3/mod/direct 7/rm32/EDI . . . 0/r32/EAX . . # copy EAX to EDI -2681 # has-modrm? = true -2682 ba/copy-to-EDX 1/imm32/true -2683 # continue -2684 e9/jump $emit-modrm:loop/disp32 -2685 $emit-modrm:check-for-subop: -2686 # if (has-metadata?(word-slice, "subop")) -2687 # . EAX = has-metadata?(ECX, "subop") -2688 # . . push args -2689 68/push "subop"/imm32 -2690 51/push-ECX -2691 # . . call -2692 e8/call has-metadata?/disp32 -2693 # . . discard args -2694 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP -2695 # . if (EAX == 0) loop -2696 3d/compare-EAX-and 0/imm32 -2697 0f 84/jump-if-equal $emit-modrm:loop/disp32 -2698 $emit-modrm:subop: -2699 # r32 = parse-hex-int(next-token-from-slice(word-slice->start, word-slice->end, '/')) -2700 # . EAX = parse-datum-of-word(word-slice) -2701 # . . push args -2702 51/push-ECX -2703 # . . call -2704 e8/call parse-datum-of-word/disp32 -2705 # . . discard args -2706 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP -2707 # . r32 = EAX -2708 89/copy 3/mod/direct 7/rm32/EDI . . . 0/r32/EAX . . # copy EAX to EDI -2709 # has-modrm? = true -2710 ba/copy-to-EDX 1/imm32/true -2711 # continue -2712 e9/jump $emit-modrm:loop/disp32 -2713 $emit-modrm:break: -2714 # if (!has-modrm?) return -2715 81 7/subop/compare 3/mod/direct 2/rm32/EDX . . . . . 0/imm32 # compare EDX -2716 74/jump-if-equal $emit-modrm:end/disp8 -2717 $emit-modrm:calculate: -2718 # modrm/EBX = mod & 0b11 -2719 81 4/subop/and 3/mod/direct 3/rm32/EBX . . . . . 3/imm32/0b11 # bitwise and of EBX -2720 # modrm <<= 2 -2721 c1/shift 4/subop/left 3/mod/direct 3/rm32/EBX . . . . . 2/imm8 # shift EBX left by 2 bits -2722 # modrm |= r32 & 0b111 -2723 81 4/subop/and 3/mod/direct 7/rm32/EDI . . . . . 7/imm32/0b111 # bitwise and of EDI -2724 09/or 3/mod/direct 3/rm32/EBX . . . 7/r32/EDI . . # EBX = bitwise OR with EDI -2725 # modrm <<= 3 -2726 c1/shift 4/subop/left 3/mod/direct 3/rm32/EBX . . . . . 3/imm8 # shift EBX left by 3 bits -2727 # modrm |= rm32 & 0b111 -2728 81 4/subop/and 3/mod/direct 6/rm32/ESI . . . . . 7/imm32/0b111 # bitwise and of ESI -2729 09/or 3/mod/direct 3/rm32/EBX . . . 6/r32/ESI . . # EBX = bitwise OR with ESI -2730 $emit-modrm:emit: -2731 # emit-hex(out, modrm, 1) -2732 # . . push args -2733 68/push 1/imm32 -2734 53/push-EBX -2735 ff 6/subop/push 1/mod/*+disp8 5/rm32/EBP . . . . 0xc/disp8 . # push *(EBP+12) -2736 # . . call -2737 e8/call emit-hex/disp32 -2738 # . . discard args -2739 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP -2740 $emit-modrm:end: -2741 # . restore locals -2742 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP -2743 # . restore registers -2744 5f/pop-to-EDI -2745 5e/pop-to-ESI -2746 5b/pop-to-EBX -2747 5a/pop-to-EDX -2748 59/pop-to-ECX -2749 58/pop-to-EAX -2750 # . epilog -2751 89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . . # copy EBP to ESP -2752 5d/pop-to-EBP -2753 c3/return -2754 -2755 emit-sib: # line : (address stream byte), out : (address buffered-file) -> <void> -2756 # pseudocode: -2757 # var has-sib? = false, base = 0, index = 0, scale = 0 -2758 # var word-slice = {0, 0} -2759 # while true -2760 # word-slice = next-word(line) -2761 # if (slice-empty?(word-slice)) break -2762 # if (slice-starts-with?(word-slice, "#")) break -2763 # if (has-metadata?(word-slice, "base") -2764 # base = parse-hex-int(next-token-from-slice(word-slice, "/")) -2765 # has-sib? = true -2766 # else if (has-metadata?(word-slice, "index") -2767 # index = parse-hex-int(next-token-from-slice(word-slice, "/")) -2768 # has-sib? = true -2769 # else if (has-metadata?(word-slice, "scale") -2770 # scale = parse-hex-int(next-token-from-slice(word-slice, "/")) -2771 # has-sib? = true -2772 # if has-sib? -2773 # var sib = scale & 0b11 -2774 # sib <<= 2 -2775 # sib |= index & 0b111 -2776 # sib <<= 3 -2777 # sib |= base & 0b111 -2778 # emit-hex(out, sib, 1) -2779 # -2780 # . prolog -2781 55/push-EBP -2782 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP -2783 # . save registers -2784 50/push-EAX +2459 # . . call +2460 e8/call parse-datum-of-word/disp32 +2461 # . . discard args +2462 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP +2463 # . mod = EAX +2464 89/copy 3/mod/direct 3/rm32/EBX . . . 0/r32/EAX . . # copy EAX to EBX +2465 # has-modrm? = true +2466 ba/copy-to-EDX 1/imm32/true +2467 # continue +2468 e9/jump $emit-modrm:loop/disp32 +2469 $emit-modrm:check-for-rm32: +2470 # if (has-metadata?(word-slice, "rm32")) +2471 # . EAX = has-metadata?(ECX, "rm32") +2472 # . . push args +2473 68/push "rm32"/imm32 +2474 51/push-ECX +2475 # . . call +2476 e8/call has-metadata?/disp32 +2477 # . . discard args +2478 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP +2479 # . if (EAX == 0) goto next check +2480 3d/compare-EAX-and 0/imm32 +2481 74/jump-if-equal $emit-modrm:check-for-r32/disp8 +2482 $emit-modrm:rm32: +2483 # rm32 = parse-hex-int(next-token-from-slice(word-slice->start, word-slice->end, '/')) +2484 # . EAX = parse-datum-of-word(word-slice) +2485 # . . push args +2486 51/push-ECX +2487 # . . call +2488 e8/call parse-datum-of-word/disp32 +2489 # . . discard args +2490 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP +2491 # . rm32 = EAX +2492 89/copy 3/mod/direct 6/rm32/ESI . . . 0/r32/EAX . . # copy EAX to ESI +2493 # has-modrm? = true +2494 ba/copy-to-EDX 1/imm32/true +2495 # continue +2496 e9/jump $emit-modrm:loop/disp32 +2497 $emit-modrm:check-for-r32: +2498 # if (has-metadata?(word-slice, "r32")) +2499 # . EAX = has-metadata?(ECX, "r32") +2500 # . . push args +2501 68/push "r32"/imm32 +2502 51/push-ECX +2503 # . . call +2504 e8/call has-metadata?/disp32 +2505 # . . discard args +2506 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP +2507 # . if (EAX == 0) goto next check +2508 3d/compare-EAX-and 0/imm32 +2509 74/jump-if-equal $emit-modrm:check-for-subop/disp8 +2510 $emit-modrm:r32: +2511 # r32 = parse-hex-int(next-token-from-slice(word-slice->start, word-slice->end, '/')) +2512 # . EAX = parse-datum-of-word(word-slice) +2513 # . . push args +2514 51/push-ECX +2515 # . . call +2516 e8/call parse-datum-of-word/disp32 +2517 # . . discard args +2518 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP +2519 # . r32 = EAX +2520 89/copy 3/mod/direct 7/rm32/EDI . . . 0/r32/EAX . . # copy EAX to EDI +2521 # has-modrm? = true +2522 ba/copy-to-EDX 1/imm32/true +2523 # continue +2524 e9/jump $emit-modrm:loop/disp32 +2525 $emit-modrm:check-for-subop: +2526 # if (has-metadata?(word-slice, "subop")) +2527 # . EAX = has-metadata?(ECX, "subop") +2528 # . . push args +2529 68/push "subop"/imm32 +2530 51/push-ECX +2531 # . . call +2532 e8/call has-metadata?/disp32 +2533 # . . discard args +2534 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP +2535 # . if (EAX == 0) loop +2536 3d/compare-EAX-and 0/imm32 +2537 0f 84/jump-if-equal $emit-modrm:loop/disp32 +2538 $emit-modrm:subop: +2539 # r32 = parse-hex-int(next-token-from-slice(word-slice->start, word-slice->end, '/')) +2540 # . EAX = parse-datum-of-word(word-slice) +2541 # . . push args +2542 51/push-ECX +2543 # . . call +2544 e8/call parse-datum-of-word/disp32 +2545 # . . discard args +2546 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP +2547 # . r32 = EAX +2548 89/copy 3/mod/direct 7/rm32/EDI . . . 0/r32/EAX . . # copy EAX to EDI +2549 # has-modrm? = true +2550 ba/copy-to-EDX 1/imm32/true +2551 # continue +2552 e9/jump $emit-modrm:loop/disp32 +2553 $emit-modrm:break: +2554 # if (!has-modrm?) return +2555 81 7/subop/compare 3/mod/direct 2/rm32/EDX . . . . . 0/imm32 # compare EDX +2556 74/jump-if-equal $emit-modrm:end/disp8 +2557 $emit-modrm:calculate: +2558 # modrm/EBX = mod & 0b11 +2559 81 4/subop/and 3/mod/direct 3/rm32/EBX . . . . . 3/imm32/0b11 # bitwise and of EBX +2560 # modrm <<= 2 +2561 c1/shift 4/subop/left 3/mod/direct 3/rm32/EBX . . . . . 2/imm8 # shift EBX left by 2 bits +2562 # modrm |= r32 & 0b111 +2563 81 4/subop/and 3/mod/direct 7/rm32/EDI . . . . . 7/imm32/0b111 # bitwise and of EDI +2564 09/or 3/mod/direct 3/rm32/EBX . . . 7/r32/EDI . . # EBX = bitwise OR with EDI +2565 # modrm <<= 3 +2566 c1/shift 4/subop/left 3/mod/direct 3/rm32/EBX . . . . . 3/imm8 # shift EBX left by 3 bits +2567 # modrm |= rm32 & 0b111 +2568 81 4/subop/and 3/mod/direct 6/rm32/ESI . . . . . 7/imm32/0b111 # bitwise and of ESI +2569 09/or 3/mod/direct 3/rm32/EBX . . . 6/r32/ESI . . # EBX = bitwise OR with ESI +2570 $emit-modrm:emit: +2571 # emit-hex(out, modrm, 1) +2572 # . . push args +2573 68/push 1/imm32 +2574 53/push-EBX +2575 ff 6/subop/push 1/mod/*+disp8 5/rm32/EBP . . . . 0xc/disp8 . # push *(EBP+12) +2576 # . . call +2577 e8/call emit-hex/disp32 +2578 # . . discard args +2579 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP +2580 $emit-modrm:end: +2581 # . restore locals +2582 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP +2583 # . restore registers +2584 5f/pop-to-EDI +2585 5e/pop-to-ESI +2586 5b/pop-to-EBX +2587 5a/pop-to-EDX +2588 59/pop-to-ECX +2589 58/pop-to-EAX +2590 # . epilog +2591 89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . . # copy EBP to ESP +2592 5d/pop-to-EBP +2593 c3/return +2594 +2595 emit-sib: # line : (address stream byte), out : (address buffered-file) -> <void> +2596 # pseudocode: +2597 # var has-sib? = false, base = 0, index = 0, scale = 0 +2598 # var word-slice = {0, 0} +2599 # while true +2600 # word-slice = next-word(line) +2601 # if (slice-empty?(word-slice)) break +2602 # if (slice-starts-with?(word-slice, "#")) break +2603 # if (has-metadata?(word-slice, "base") +2604 # base = parse-hex-int(next-token-from-slice(word-slice, "/")) +2605 # has-sib? = true +2606 # else if (has-metadata?(word-slice, "index") +2607 # index = parse-hex-int(next-token-from-slice(word-slice, "/")) +2608 # has-sib? = true +2609 # else if (has-metadata?(word-slice, "scale") +2610 # scale = parse-hex-int(next-token-from-slice(word-slice, "/")) +2611 # has-sib? = true +2612 # if has-sib? +2613 # var sib = scale & 0b11 +2614 # sib <<= 2 +2615 # sib |= index & 0b111 +2616 # sib <<= 3 +2617 # sib |= base & 0b111 +2618 # emit-hex(out, sib, 1) +2619 # +2620 # . prolog +2621 55/push-EBP +2622 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP +2623 # . save registers +2624 50/push-EAX +2625 51/push-ECX +2626 52/push-EDX +2627 53/push-EBX +2628 56/push-ESI +2629 57/push-EDI +2630 # var word-slice/ECX = {0, 0} +2631 68/push 0/imm32/end +2632 68/push 0/imm32/start +2633 89/copy 3/mod/direct 1/rm32/ECX . . . 4/r32/ESP . . # copy ESP to ECX +2634 # var has-sib?/EDX = false +2635 31/xor 3/mod/direct 2/rm32/EDX . . . 2/r32/EDX . . # clear EDX +2636 # var scale/EBX = 0 +2637 31/xor 3/mod/direct 3/rm32/EBX . . . 3/r32/EBX . . # clear EBX +2638 # var base/ESI = 0 +2639 31/xor 3/mod/direct 6/rm32/ESI . . . 6/r32/ESI . . # clear ESI +2640 # var index/EDI = 0 +2641 31/xor 3/mod/direct 7/rm32/EDI . . . 7/r32/EDI . . # clear EDI +2642 # rewind-stream(line) +2643 # . . push args +2644 ff 6/subop/push 1/mod/*+disp8 5/rm32/EBP . . . . 8/disp8 . # push *(EBP+8) +2645 # . . call +2646 e8/call rewind-stream/disp32 +2647 # . . discard args +2648 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP +2649 $emit-sib:loop: +2650 +-- 26 lines: #? # dump line ----------------------------------------------------------------------------------------------------------------------------- +2676 # next-word(line, word-slice) +2677 # . . push args +2678 51/push-ECX +2679 ff 6/subop/push 1/mod/*+disp8 5/rm32/EBP . . . . 8/disp8 . # push *(EBP+8) +2680 # . . call +2681 e8/call next-word/disp32 +2682 # . . discard args +2683 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP +2684 +-- 42 lines: #? # dump word-slice ----------------------------------------------------------------------------------------------------------------------- +2726 $emit-sib:check0: +2727 # if (slice-empty?(word-slice)) break +2728 # . EAX = slice-empty?(word-slice) +2729 # . . push args +2730 51/push-ECX +2731 # . . call +2732 e8/call slice-empty?/disp32 +2733 # . . discard args +2734 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP +2735 # . if (EAX != 0) pass through +2736 3d/compare-EAX-and 0/imm32 +2737 0f 85/jump-if-not-equal $emit-sib:break/disp32 +2738 $emit-sib:check1: +2739 # if (slice-starts-with?(word-slice, "#")) break +2740 # . spill EDX +2741 52/push-EDX +2742 # . start/EDX = word-slice->start +2743 8b/copy 0/mod/indirect 1/rm32/ECX . . . 2/r32/EDX . . # copy *ECX to EDX +2744 # . c/EAX = *start +2745 31/xor 3/mod/direct 0/rm32/EAX . . . 0/r32/EAX . . # clear EAX +2746 8a/copy-byte 0/mod/indirect 2/rm32/EDX . . . 0/r32/AL . . # copy byte at *EDX to AL +2747 # . restore EDX +2748 5a/pop-to-EDX +2749 # . if (EAX == '#') pass through +2750 3d/compare-EAX-and 0x23/imm32/hash +2751 0f 84/jump-if-equal $emit-sib:break/disp32 +2752 $emit-sib:check-for-scale: +2753 # if (has-metadata?(word-slice, "scale")) +2754 # . EAX = has-metadata?(ECX, "scale") +2755 # . . push args +2756 68/push "scale"/imm32 +2757 51/push-ECX +2758 # . . call +2759 e8/call has-metadata?/disp32 +2760 # . . discard args +2761 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP +2762 # . if (EAX == 0) goto next check +2763 3d/compare-EAX-and 0/imm32 +2764 74/jump-if-equal $emit-sib:check-for-base/disp8 +2765 $emit-sib:scale: +2766 # scale = parse-hex-int(next-token-from-slice(word-slice->start, word-slice->end, '/')) +2767 # . EAX = parse-datum-of-word(word-slice) +2768 # . . push args +2769 51/push-ECX +2770 # . . call +2771 e8/call parse-datum-of-word/disp32 +2772 # . . discard args +2773 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP +2774 # . scale = EAX +2775 89/copy 3/mod/direct 3/rm32/EBX . . . 0/r32/EAX . . # copy EAX to EBX +2776 # has-sib? = true +2777 ba/copy-to-EDX 1/imm32/true +2778 # continue +2779 e9/jump $emit-sib:loop/disp32 +2780 $emit-sib:check-for-base: +2781 # if (has-metadata?(word-slice, "base")) +2782 # . EAX = has-metadata?(ECX, "base") +2783 # . . push args +2784 68/push "base"/imm32 2785 51/push-ECX -2786 52/push-EDX -2787 53/push-EBX -2788 56/push-ESI -2789 57/push-EDI -2790 # var word-slice/ECX = {0, 0} -2791 68/push 0/imm32/end -2792 68/push 0/imm32/start -2793 89/copy 3/mod/direct 1/rm32/ECX . . . 4/r32/ESP . . # copy ESP to ECX -2794 # var has-sib?/EDX = false -2795 31/xor 3/mod/direct 2/rm32/EDX . . . 2/r32/EDX . . # clear EDX -2796 # var scale/EBX = 0 -2797 31/xor 3/mod/direct 3/rm32/EBX . . . 3/r32/EBX . . # clear EBX -2798 # var base/ESI = 0 -2799 31/xor 3/mod/direct 6/rm32/ESI . . . 6/r32/ESI . . # clear ESI -2800 # var index/EDI = 0 -2801 31/xor 3/mod/direct 7/rm32/EDI . . . 7/r32/EDI . . # clear EDI -2802 # rewind-stream(line) -2803 # . . push args -2804 ff 6/subop/push 1/mod/*+disp8 5/rm32/EBP . . . . 8/disp8 . # push *(EBP+8) -2805 # . . call -2806 e8/call rewind-stream/disp32 -2807 # . . discard args -2808 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP -2809 $emit-sib:loop: -2810 +-- 34 lines: #? # dump line ----------------------------------------------------------------------------------------------------------------------------- -2844 # next-word(line, word-slice) -2845 # . . push args -2846 51/push-ECX -2847 ff 6/subop/push 1/mod/*+disp8 5/rm32/EBP . . . . 8/disp8 . # push *(EBP+8) -2848 # . . call -2849 e8/call next-word/disp32 -2850 # . . discard args -2851 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP -2852 +-- 50 lines: #? # dump word-slice ----------------------------------------------------------------------------------------------------------------------- -2902 $emit-sib:check0: -2903 # if (slice-empty?(word-slice)) break -2904 # . EAX = slice-empty?(word-slice) -2905 # . . push args -2906 51/push-ECX -2907 # . . call -2908 e8/call slice-empty?/disp32 -2909 # . . discard args -2910 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP -2911 # . if (EAX != 0) pass through -2912 3d/compare-EAX-and 0/imm32 -2913 0f 85/jump-if-not-equal $emit-sib:break/disp32 -2914 $emit-sib:check1: -2915 # if (slice-starts-with?(word-slice, "#")) break -2916 # . spill EDX -2917 52/push-EDX -2918 # . start/EDX = word-slice->start -2919 8b/copy 0/mod/indirect 1/rm32/ECX . . . 2/r32/EDX . . # copy *ECX to EDX -2920 # . c/EAX = *start -2921 31/xor 3/mod/direct 0/rm32/EAX . . . 0/r32/EAX . . # clear EAX -2922 8a/copy-byte 0/mod/indirect 2/rm32/EDX . . . 0/r32/AL . . # copy byte at *EDX to AL -2923 # . restore EDX -2924 5a/pop-to-EDX -2925 # . if (EAX == '#') pass through -2926 3d/compare-EAX-and 0x23/imm32/hash -2927 0f 84/jump-if-equal $emit-sib:break/disp32 -2928 $emit-sib:check-for-scale: -2929 # if (has-metadata?(word-slice, "scale")) -2930 # . EAX = has-metadata?(ECX, "scale") -2931 # . . push args -2932 68/push "scale"/imm32 -2933 51/push-ECX -2934 # . . call -2935 e8/call has-metadata?/disp32 -2936 # . . discard args -2937 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP -2938 # . if (EAX == 0) goto next check -2939 3d/compare-EAX-and 0/imm32 -2940 74/jump-if-equal $emit-sib:check-for-base/disp8 -2941 $emit-sib:scale: -2942 # scale = parse-hex-int(next-token-from-slice(word-slice->start, word-slice->end, '/')) -2943 # . EAX = parse-datum-of-word(word-slice) -2944 # . . push args -2945 51/push-ECX -2946 # . . call -2947 e8/call parse-datum-of-word/disp32 -2948 # . . discard args -2949 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP -2950 # . scale = EAX -2951 89/copy 3/mod/direct 3/rm32/EBX . . . 0/r32/EAX . . # copy EAX to EBX -2952 # has-sib? = true -2953 ba/copy-to-EDX 1/imm32/true -2954 # continue -2955 e9/jump $emit-sib:loop/disp32 -2956 $emit-sib:check-for-base: -2957 # if (has-metadata?(word-slice, "base")) -2958 # . EAX = has-metadata?(ECX, "base") -2959 # . . push args -2960 68/push "base"/imm32 -2961 51/push-ECX -2962 # . . call -2963 e8/call has-metadata?/disp32 -2964 # . . discard args -2965 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP -2966 # . if (EAX == 0) goto next check -2967 3d/compare-EAX-and 0/imm32 -2968 74/jump-if-equal $emit-sib:check-for-index/disp8 -2969 $emit-sib:base: -2970 # base = parse-hex-int(next-token-from-slice(word-slice->start, word-slice->end, '/')) -2971 # . EAX = parse-datum-of-word(word-slice) -2972 # . . push args -2973 51/push-ECX -2974 # . . call -2975 e8/call parse-datum-of-word/disp32 -2976 # . . discard args -2977 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP -2978 # . base = EAX -2979 89/copy 3/mod/direct 6/rm32/ESI . . . 0/r32/EAX . . # copy EAX to ESI -2980 # has-sib? = true -2981 ba/copy-to-EDX 1/imm32/true -2982 # continue -2983 e9/jump $emit-sib:loop/disp32 -2984 $emit-sib:check-for-index: -2985 # if (has-metadata?(word-slice, "index")) -2986 # . EAX = has-metadata?(ECX, "index") -2987 # . . push args -2988 68/push "index"/imm32 -2989 51/push-ECX -2990 # . . call -2991 e8/call has-metadata?/disp32 -2992 # . . discard args -2993 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP -2994 # . if (EAX == 0) loop -2995 3d/compare-EAX-and 0/imm32 -2996 0f 84/jump-if-equal $emit-sib:loop/disp32 -2997 $emit-sib:index: -2998 # index = parse-hex-int(next-token-from-slice(word-slice->start, word-slice->end, '/')) -2999 # . EAX = parse-datum-of-word(word-slice) -3000 # . . push args -3001 51/push-ECX -3002 # . . call -3003 e8/call parse-datum-of-word/disp32 -3004 # . . discard args -3005 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP -3006 # . index = EAX -3007 89/copy 3/mod/direct 7/rm32/EDI . . . 0/r32/EAX . . # copy EAX to EDI -3008 # has-sib? = true -3009 ba/copy-to-EDX 1/imm32/true -3010 # continue -3011 e9/jump $emit-sib:loop/disp32 -3012 $emit-sib:break: -3013 # if (!has-sib?) return -3014 81 7/subop/compare 3/mod/direct 2/rm32/EDX . . . . . 0/imm32 # compare EDX -3015 74/jump-if-equal $emit-sib:end/disp8 -3016 $emit-sib:calculate: -3017 # sib/EBX = scale & 0b11 -3018 81 4/subop/and 3/mod/direct 3/rm32/EBX . . . . . 3/imm32/0b11 # bitwise and of EBX -3019 # sib <<= 2 -3020 c1/shift 4/subop/left 3/mod/direct 3/rm32/EBX . . . . . 2/imm8 # shift EBX left by 2 bits -3021 # sib |= index & 0b111 -3022 81 4/subop/and 3/mod/direct 7/rm32/EDI . . . . . 7/imm32/0b111 # bitwise and of EDI -3023 09/or 3/mod/direct 3/rm32/EBX . . . 7/r32/EDI . . # EBX = bitwise OR with EDI -3024 # sib <<= 3 -3025 c1/shift 4/subop/left 3/mod/direct 3/rm32/EBX . . . . . 3/imm8 # shift EBX left by 3 bits -3026 # sib |= base & 0b111 -3027 81 4/subop/and 3/mod/direct 6/rm32/ESI . . . . . 7/imm32/0b111 # bitwise and of ESI -3028 09/or 3/mod/direct 3/rm32/EBX . . . 6/r32/ESI . . # EBX = bitwise OR with ESI -3029 $emit-sib:emit: -3030 # emit-hex(out, sib, 1) -3031 # . . push args -3032 68/push 1/imm32 -3033 53/push-EBX -3034 ff 6/subop/push 1/mod/*+disp8 5/rm32/EBP . . . . 0xc/disp8 . # push *(EBP+12) -3035 # . . call -3036 e8/call emit-hex/disp32 -3037 # . . discard args -3038 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP -3039 $emit-sib:end: -3040 # . restore locals -3041 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP -3042 # . restore registers -3043 5f/pop-to-EDI -3044 5e/pop-to-ESI -3045 5b/pop-to-EBX -3046 5a/pop-to-EDX -3047 59/pop-to-ECX -3048 58/pop-to-EAX -3049 # . epilog -3050 89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . . # copy EBP to ESP -3051 5d/pop-to-EBP -3052 c3/return -3053 -3054 emit-disp: # line : (address stream byte), out : (address buffered-file) -> <void> -3055 # pseudocode: -3056 # rewind-stream(line) -3057 # var word-slice = {0, 0} -3058 # while true -3059 # word-slice = next-word(line) -3060 # if (slice-empty?(word-slice)) break -3061 # if (slice-starts-with?(word-slice, "#")) break -3062 # if has-metadata?(word-slice, "disp32") -3063 # emit(out, word-slice, 4) -3064 # break -3065 # if has-metadata?(word-slice, "disp16") -3066 # emit(out, word-slice, 2) -3067 # break -3068 # if has-metadata?(word-slice, "disp8") -3069 # emit(out, word-slice, 1) -3070 # break -3071 # -3072 # . prolog -3073 55/push-EBP -3074 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP -3075 # . save registers -3076 50/push-EAX -3077 51/push-ECX -3078 52/push-EDX -3079 # var word-slice/ECX = {0, 0} -3080 68/push 0/imm32/end -3081 68/push 0/imm32/start -3082 89/copy 3/mod/direct 1/rm32/ECX . . . 4/r32/ESP . . # copy ESP to ECX -3083 # rewind-stream(line) -3084 # . . push args -3085 ff 6/subop/push 1/mod/*+disp8 5/rm32/EBP . . . . 8/disp8 . # push *(EBP+8) -3086 # . . call -3087 e8/call rewind-stream/disp32 -3088 # . . discard args -3089 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP -3090 +-- 34 lines: #? # dump line ----------------------------------------------------------------------------------------------------------------------------- -3124 $emit-disp:loop: -3125 # next-word(line, word-slice) -3126 # . . push args -3127 51/push-ECX -3128 ff 6/subop/push 1/mod/*+disp8 5/rm32/EBP . . . . 8/disp8 . # push *(EBP+8) -3129 # . . call -3130 e8/call next-word/disp32 -3131 # . . discard args -3132 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP -3133 +-- 50 lines: #? # dump word-slice ----------------------------------------------------------------------------------------------------------------------- -3183 $emit-disp:check0: -3184 # if (slice-empty?(word-slice)) break -3185 # . EAX = slice-empty?(word-slice) -3186 # . . push args -3187 51/push-ECX -3188 # . . call -3189 e8/call slice-empty?/disp32 -3190 # . . discard args -3191 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP -3192 # . if (EAX != 0) pass through -3193 3d/compare-EAX-and 0/imm32 -3194 0f 85/jump-if-not-equal $emit-disp:break/disp32 -3195 $emit-disp:check1: -3196 # if (slice-starts-with?(word-slice, "#")) break -3197 # . start/EDX = word-slice->start -3198 8b/copy 0/mod/indirect 1/rm32/ECX . . . 2/r32/EDX . . # copy *ECX to EDX -3199 # . c/EAX = *start -3200 31/xor 3/mod/direct 0/rm32/EAX . . . 0/r32/EAX . . # clear EAX -3201 8a/copy-byte 0/mod/indirect 2/rm32/EDX . . . 0/r32/AL . . # copy byte at *EDX to AL -3202 # . if (EAX == '#') break -3203 3d/compare-EAX-and 0x23/imm32/hash -3204 0f 84/jump-if-equal $emit-disp:break/disp32 -3205 $emit-disp:check-for-disp32: -3206 # if (has-metadata?(word-slice, "disp32")) -3207 # . EAX = has-metadata?(ECX, "disp32") -3208 # . . push args -3209 68/push "disp32"/imm32 -3210 51/push-ECX -3211 # . . call -3212 e8/call has-metadata?/disp32 -3213 # . . discard args -3214 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP -3215 # . if (EAX == 0) goto next check -3216 3d/compare-EAX-and 0/imm32 -3217 74/jump-if-equal $emit-disp:check-for-disp16/disp8 -3218 $emit-disp:disp32: -3219 # emit(out, word-slice, 4) -3220 # . . push args -3221 68/push 4/imm32 -3222 51/push-ECX -3223 ff 6/subop/push 1/mod/*+disp8 5/rm32/EBP . . . . 0xc/disp8 . # push *(EBP+12) -3224 # . . call -3225 e8/call emit/disp32 -3226 # . . discard args -3227 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP -3228 # break -3229 e9/jump $emit-disp:break/disp32 -3230 $emit-disp:check-for-disp16: -3231 # else if (has-metadata?(word-slice, "disp16")) -3232 # . EAX = has-metadata?(ECX, "disp16") -3233 # . . push args -3234 68/push "disp16"/imm32 -3235 51/push-ECX -3236 # . . call -3237 e8/call has-metadata?/disp32 -3238 # . . discard args -3239 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP -3240 # . if (EAX == 0) goto next check -3241 3d/compare-EAX-and 0/imm32 -3242 74/jump-if-equal $emit-disp:check-for-disp8/disp8 -3243 $emit-disp:disp16: -3244 # emit(out, word-slice, 2) -3245 # . . push args -3246 68/push 2/imm32 -3247 51/push-ECX -3248 ff 6/subop/push 1/mod/*+disp8 5/rm32/EBP . . . . 0xc/disp8 . # push *(EBP+12) -3249 # . . call -3250 e8/call emit/disp32 -3251 # . . discard args -3252 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP -3253 # break -3254 e9/jump $emit-disp:break/disp32 -3255 $emit-disp:check-for-disp8: -3256 # if (has-metadata?(word-slice, "disp8")) -3257 # . EAX = has-metadata?(ECX, "disp8") -3258 # . . push args -3259 68/push "disp8"/imm32 -3260 51/push-ECX -3261 # . . call -3262 e8/call has-metadata?/disp32 -3263 # . . discard args -3264 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP -3265 # . if (EAX == 0) loop -3266 3d/compare-EAX-and 0/imm32 -3267 0f 84/jump-if-equal $emit-disp:loop/disp32 -3268 $emit-disp:disp8: -3269 # emit(out, word-slice, 1) -3270 # . . push args -3271 68/push 1/imm32 -3272 51/push-ECX -3273 ff 6/subop/push 1/mod/*+disp8 5/rm32/EBP . . . . 0xc/disp8 . # push *(EBP+12) -3274 # . . call -3275 e8/call emit/disp32 -3276 # . . discard args -3277 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP -3278 # break -3279 $emit-disp:break: -3280 # . restore locals -3281 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP -3282 # . restore registers -3283 5a/pop-to-EDX -3284 59/pop-to-ECX -3285 58/pop-to-EAX -3286 # . epilog -3287 89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . . # copy EBP to ESP -3288 5d/pop-to-EBP -3289 c3/return -3290 -3291 emit-imm: # line : (address stream byte), out : (address buffered-file) -> <void> -3292 # pseudocode: -3293 # rewind-stream(line) -3294 # var word-slice = {0, 0} -3295 # while true -3296 # word-slice = next-word(line) -3297 # if (slice-empty?(word-slice)) break -3298 # if (slice-starts-with?(word-slice, "#")) break -3299 # if has-metadata?(word-slice, "imm32") -3300 # emit(out, word-slice, 4) -3301 # break -3302 # if has-metadata?(word-slice, "imm16") -3303 # emit(out, word-slice, 2) -3304 # break -3305 # if has-metadata?(word-slice, "imm8") -3306 # emit(out, word-slice, 1) -3307 # break -3308 # -3309 # . prolog -3310 55/push-EBP -3311 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP -3312 # . save registers -3313 50/push-EAX -3314 51/push-ECX -3315 52/push-EDX -3316 # var word-slice/ECX = {0, 0} -3317 68/push 0/imm32/end -3318 68/push 0/imm32/start -3319 89/copy 3/mod/direct 1/rm32/ECX . . . 4/r32/ESP . . # copy ESP to ECX -3320 # rewind-stream(line) -3321 # . . push args -3322 ff 6/subop/push 1/mod/*+disp8 5/rm32/EBP . . . . 8/disp8 . # push *(EBP+8) -3323 # . . call -3324 e8/call rewind-stream/disp32 -3325 # . . discard args -3326 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP -3327 +-- 34 lines: #? # dump line ----------------------------------------------------------------------------------------------------------------------------- -3361 $emit-imm:loop: -3362 # next-word(line, word-slice) -3363 # . . push args -3364 51/push-ECX -3365 ff 6/subop/push 1/mod/*+disp8 5/rm32/EBP . . . . 8/disp8 . # push *(EBP+8) -3366 # . . call -3367 e8/call next-word/disp32 -3368 # . . discard args -3369 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP -3370 +-- 50 lines: #? # dump word-slice ----------------------------------------------------------------------------------------------------------------------- -3420 $emit-imm:check0: -3421 # if (slice-empty?(word-slice)) break -3422 # . EAX = slice-empty?(word-slice) -3423 # . . push args -3424 51/push-ECX -3425 # . . call -3426 e8/call slice-empty?/disp32 -3427 # . . discard args -3428 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP -3429 # . if (EAX != 0) pass through -3430 3d/compare-EAX-and 0/imm32 -3431 0f 85/jump-if-not-equal $emit-imm:break/disp32 -3432 $emit-imm:check1: -3433 # if (slice-starts-with?(word-slice, "#")) break -3434 # . start/EDX = slice->start -3435 8b/copy 0/mod/indirect 1/rm32/ECX . . . 2/r32/EDX . . # copy *ECX to EDX -3436 # . c/EAX = *start -3437 31/xor 3/mod/direct 0/rm32/EAX . . . 0/r32/EAX . . # clear EAX -3438 8a/copy-byte 0/mod/indirect 2/rm32/EDX . . . 0/r32/AL . . # copy byte at *EDX to AL -3439 # . if (EAX == '#') break -3440 3d/compare-EAX-and 0x23/imm32/hash -3441 0f 84/jump-if-equal $emit-imm:break/disp32 -3442 $emit-imm:check-for-imm32: -3443 # if (has-metadata?(word-slice, "imm32")) -3444 # . EAX = has-metadata?(ECX, "imm32") +2786 # . . call +2787 e8/call has-metadata?/disp32 +2788 # . . discard args +2789 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP +2790 # . if (EAX == 0) goto next check +2791 3d/compare-EAX-and 0/imm32 +2792 74/jump-if-equal $emit-sib:check-for-index/disp8 +2793 $emit-sib:base: +2794 # base = parse-hex-int(next-token-from-slice(word-slice->start, word-slice->end, '/')) +2795 # . EAX = parse-datum-of-word(word-slice) +2796 # . . push args +2797 51/push-ECX +2798 # . . call +2799 e8/call parse-datum-of-word/disp32 +2800 # . . discard args +2801 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP +2802 # . base = EAX +2803 89/copy 3/mod/direct 6/rm32/ESI . . . 0/r32/EAX . . # copy EAX to ESI +2804 # has-sib? = true +2805 ba/copy-to-EDX 1/imm32/true +2806 # continue +2807 e9/jump $emit-sib:loop/disp32 +2808 $emit-sib:check-for-index: +2809 # if (has-metadata?(word-slice, "index")) +2810 # . EAX = has-metadata?(ECX, "index") +2811 # . . push args +2812 68/push "index"/imm32 +2813 51/push-ECX +2814 # . . call +2815 e8/call has-metadata?/disp32 +2816 # . . discard args +2817 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP +2818 # . if (EAX == 0) loop +2819 3d/compare-EAX-and 0/imm32 +2820 0f 84/jump-if-equal $emit-sib:loop/disp32 +2821 $emit-sib:index: +2822 # index = parse-hex-int(next-token-from-slice(word-slice->start, word-slice->end, '/')) +2823 # . EAX = parse-datum-of-word(word-slice) +2824 # . . push args +2825 51/push-ECX +2826 # . . call +2827 e8/call parse-datum-of-word/disp32 +2828 # . . discard args +2829 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP +2830 # . index = EAX +2831 89/copy 3/mod/direct 7/rm32/EDI . . . 0/r32/EAX . . # copy EAX to EDI +2832 # has-sib? = true +2833 ba/copy-to-EDX 1/imm32/true +2834 # continue +2835 e9/jump $emit-sib:loop/disp32 +2836 $emit-sib:break: +2837 # if (!has-sib?) return +2838 81 7/subop/compare 3/mod/direct 2/rm32/EDX . . . . . 0/imm32 # compare EDX +2839 74/jump-if-equal $emit-sib:end/disp8 +2840 $emit-sib:calculate: +2841 # sib/EBX = scale & 0b11 +2842 81 4/subop/and 3/mod/direct 3/rm32/EBX . . . . . 3/imm32/0b11 # bitwise and of EBX +2843 # sib <<= 2 +2844 c1/shift 4/subop/left 3/mod/direct 3/rm32/EBX . . . . . 2/imm8 # shift EBX left by 2 bits +2845 # sib |= index & 0b111 +2846 81 4/subop/and 3/mod/direct 7/rm32/EDI . . . . . 7/imm32/0b111 # bitwise and of EDI +2847 09/or 3/mod/direct 3/rm32/EBX . . . 7/r32/EDI . . # EBX = bitwise OR with EDI +2848 # sib <<= 3 +2849 c1/shift 4/subop/left 3/mod/direct 3/rm32/EBX . . . . . 3/imm8 # shift EBX left by 3 bits +2850 # sib |= base & 0b111 +2851 81 4/subop/and 3/mod/direct 6/rm32/ESI . . . . . 7/imm32/0b111 # bitwise and of ESI +2852 09/or 3/mod/direct 3/rm32/EBX . . . 6/r32/ESI . . # EBX = bitwise OR with ESI +2853 $emit-sib:emit: +2854 # emit-hex(out, sib, 1) +2855 # . . push args +2856 68/push 1/imm32 +2857 53/push-EBX +2858 ff 6/subop/push 1/mod/*+disp8 5/rm32/EBP . . . . 0xc/disp8 . # push *(EBP+12) +2859 # . . call +2860 e8/call emit-hex/disp32 +2861 # . . discard args +2862 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP +2863 $emit-sib:end: +2864 # . restore locals +2865 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP +2866 # . restore registers +2867 5f/pop-to-EDI +2868 5e/pop-to-ESI +2869 5b/pop-to-EBX +2870 5a/pop-to-EDX +2871 59/pop-to-ECX +2872 58/pop-to-EAX +2873 # . epilog +2874 89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . . # copy EBP to ESP +2875 5d/pop-to-EBP +2876 c3/return +2877 +2878 emit-disp: # line : (address stream byte), out : (address buffered-file) -> <void> +2879 # pseudocode: +2880 # rewind-stream(line) +2881 # var word-slice = {0, 0} +2882 # while true +2883 # word-slice = next-word(line) +2884 # if (slice-empty?(word-slice)) break +2885 # if (slice-starts-with?(word-slice, "#")) break +2886 # if has-metadata?(word-slice, "disp32") +2887 # emit(out, word-slice, 4) +2888 # break +2889 # if has-metadata?(word-slice, "disp16") +2890 # emit(out, word-slice, 2) +2891 # break +2892 # if has-metadata?(word-slice, "disp8") +2893 # emit(out, word-slice, 1) +2894 # break +2895 # +2896 # . prolog +2897 55/push-EBP +2898 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP +2899 # . save registers +2900 50/push-EAX +2901 51/push-ECX +2902 52/push-EDX +2903 # var word-slice/ECX = {0, 0} +2904 68/push 0/imm32/end +2905 68/push 0/imm32/start +2906 89/copy 3/mod/direct 1/rm32/ECX . . . 4/r32/ESP . . # copy ESP to ECX +2907 # rewind-stream(line) +2908 # . . push args +2909 ff 6/subop/push 1/mod/*+disp8 5/rm32/EBP . . . . 8/disp8 . # push *(EBP+8) +2910 # . . call +2911 e8/call rewind-stream/disp32 +2912 # . . discard args +2913 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP +2914 +-- 26 lines: #? # dump line ----------------------------------------------------------------------------------------------------------------------------- +2940 $emit-disp:loop: +2941 # next-word(line, word-slice) +2942 # . . push args +2943 51/push-ECX +2944 ff 6/subop/push 1/mod/*+disp8 5/rm32/EBP . . . . 8/disp8 . # push *(EBP+8) +2945 # . . call +2946 e8/call next-word/disp32 +2947 # . . discard args +2948 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP +2949 +-- 42 lines: #? # dump word-slice ----------------------------------------------------------------------------------------------------------------------- +2991 $emit-disp:check0: +2992 # if (slice-empty?(word-slice)) break +2993 # . EAX = slice-empty?(word-slice) +2994 # . . push args +2995 51/push-ECX +2996 # . . call +2997 e8/call slice-empty?/disp32 +2998 # . . discard args +2999 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP +3000 # . if (EAX != 0) pass through +3001 3d/compare-EAX-and 0/imm32 +3002 0f 85/jump-if-not-equal $emit-disp:break/disp32 +3003 $emit-disp:check1: +3004 # if (slice-starts-with?(word-slice, "#")) break +3005 # . start/EDX = word-slice->start +3006 8b/copy 0/mod/indirect 1/rm32/ECX . . . 2/r32/EDX . . # copy *ECX to EDX +3007 # . c/EAX = *start +3008 31/xor 3/mod/direct 0/rm32/EAX . . . 0/r32/EAX . . # clear EAX +3009 8a/copy-byte 0/mod/indirect 2/rm32/EDX . . . 0/r32/AL . . # copy byte at *EDX to AL +3010 # . if (EAX == '#') break +3011 3d/compare-EAX-and 0x23/imm32/hash +3012 0f 84/jump-if-equal $emit-disp:break/disp32 +3013 $emit-disp:check-for-disp32: +3014 # if (has-metadata?(word-slice, "disp32")) +3015 # . EAX = has-metadata?(ECX, "disp32") +3016 # . . push args +3017 68/push "disp32"/imm32 +3018 51/push-ECX +3019 # . . call +3020 e8/call has-metadata?/disp32 +3021 # . . discard args +3022 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP +3023 # . if (EAX == 0) goto next check +3024 3d/compare-EAX-and 0/imm32 +3025 74/jump-if-equal $emit-disp:check-for-disp16/disp8 +3026 $emit-disp:disp32: +3027 # emit(out, word-slice, 4) +3028 # . . push args +3029 68/push 4/imm32 +3030 51/push-ECX +3031 ff 6/subop/push 1/mod/*+disp8 5/rm32/EBP . . . . 0xc/disp8 . # push *(EBP+12) +3032 # . . call +3033 e8/call emit/disp32 +3034 # . . discard args +3035 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP +3036 # break +3037 e9/jump $emit-disp:break/disp32 +3038 $emit-disp:check-for-disp16: +3039 # else if (has-metadata?(word-slice, "disp16")) +3040 # . EAX = has-metadata?(ECX, "disp16") +3041 # . . push args +3042 68/push "disp16"/imm32 +3043 51/push-ECX +3044 # . . call +3045 e8/call has-metadata?/disp32 +3046 # . . discard args +3047 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP +3048 # . if (EAX == 0) goto next check +3049 3d/compare-EAX-and 0/imm32 +3050 74/jump-if-equal $emit-disp:check-for-disp8/disp8 +3051 $emit-disp:disp16: +3052 # emit(out, word-slice, 2) +3053 # . . push args +3054 68/push 2/imm32 +3055 51/push-ECX +3056 ff 6/subop/push 1/mod/*+disp8 5/rm32/EBP . . . . 0xc/disp8 . # push *(EBP+12) +3057 # . . call +3058 e8/call emit/disp32 +3059 # . . discard args +3060 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP +3061 # break +3062 e9/jump $emit-disp:break/disp32 +3063 $emit-disp:check-for-disp8: +3064 # if (has-metadata?(word-slice, "disp8")) +3065 # . EAX = has-metadata?(ECX, "disp8") +3066 # . . push args +3067 68/push "disp8"/imm32 +3068 51/push-ECX +3069 # . . call +3070 e8/call has-metadata?/disp32 +3071 # . . discard args +3072 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP +3073 # . if (EAX == 0) loop +3074 3d/compare-EAX-and 0/imm32 +3075 0f 84/jump-if-equal $emit-disp:loop/disp32 +3076 $emit-disp:disp8: +3077 # emit(out, word-slice, 1) +3078 # . . push args +3079 68/push 1/imm32 +3080 51/push-ECX +3081 ff 6/subop/push 1/mod/*+disp8 5/rm32/EBP . . . . 0xc/disp8 . # push *(EBP+12) +3082 # . . call +3083 e8/call emit/disp32 +3084 # . . discard args +3085 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP +3086 # break +3087 $emit-disp:break: +3088 # . restore locals +3089 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP +3090 # . restore registers +3091 5a/pop-to-EDX +3092 59/pop-to-ECX +3093 58/pop-to-EAX +3094 # . epilog +3095 89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . . # copy EBP to ESP +3096 5d/pop-to-EBP +3097 c3/return +3098 +3099 emit-imm: # line : (address stream byte), out : (address buffered-file) -> <void> +3100 # pseudocode: +3101 # rewind-stream(line) +3102 # var word-slice = {0, 0} +3103 # while true +3104 # word-slice = next-word(line) +3105 # if (slice-empty?(word-slice)) break +3106 # if (slice-starts-with?(word-slice, "#")) break +3107 # if has-metadata?(word-slice, "imm32") +3108 # emit(out, word-slice, 4) +3109 # break +3110 # if has-metadata?(word-slice, "imm16") +3111 # emit(out, word-slice, 2) +3112 # break +3113 # if has-metadata?(word-slice, "imm8") +3114 # emit(out, word-slice, 1) +3115 # break +3116 # +3117 # . prolog +3118 55/push-EBP +3119 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP +3120 # . save registers +3121 50/push-EAX +3122 51/push-ECX +3123 52/push-EDX +3124 # var word-slice/ECX = {0, 0} +3125 68/push 0/imm32/end +3126 68/push 0/imm32/start +3127 89/copy 3/mod/direct 1/rm32/ECX . . . 4/r32/ESP . . # copy ESP to ECX +3128 # rewind-stream(line) +3129 # . . push args +3130 ff 6/subop/push 1/mod/*+disp8 5/rm32/EBP . . . . 8/disp8 . # push *(EBP+8) +3131 # . . call +3132 e8/call rewind-stream/disp32 +3133 # . . discard args +3134 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP +3135 +-- 26 lines: #? # dump line ----------------------------------------------------------------------------------------------------------------------------- +3161 $emit-imm:loop: +3162 # next-word(line, word-slice) +3163 # . . push args +3164 51/push-ECX +3165 ff 6/subop/push 1/mod/*+disp8 5/rm32/EBP . . . . 8/disp8 . # push *(EBP+8) +3166 # . . call +3167 e8/call next-word/disp32 +3168 # . . discard args +3169 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP +3170 +-- 42 lines: #? # dump word-slice ----------------------------------------------------------------------------------------------------------------------- +3212 $emit-imm:check0: +3213 # if (slice-empty?(word-slice)) break +3214 # . EAX = slice-empty?(word-slice) +3215 # . . push args +3216 51/push-ECX +3217 # . . call +3218 e8/call slice-empty?/disp32 +3219 # . . discard args +3220 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP +3221 # . if (EAX != 0) pass through +3222 3d/compare-EAX-and 0/imm32 +3223 0f 85/jump-if-not-equal $emit-imm:break/disp32 +3224 $emit-imm:check1: +3225 # if (slice-starts-with?(word-slice, "#")) break +3226 # . start/EDX = slice->start +3227 8b/copy 0/mod/indirect 1/rm32/ECX . . . 2/r32/EDX . . # copy *ECX to EDX +3228 # . c/EAX = *start +3229 31/xor 3/mod/direct 0/rm32/EAX . . . 0/r32/EAX . . # clear EAX +3230 8a/copy-byte 0/mod/indirect 2/rm32/EDX . . . 0/r32/AL . . # copy byte at *EDX to AL +3231 # . if (EAX == '#') break +3232 3d/compare-EAX-and 0x23/imm32/hash +3233 0f 84/jump-if-equal $emit-imm:break/disp32 +3234 $emit-imm:check-for-imm32: +3235 # if (has-metadata?(word-slice, "imm32")) +3236 # . EAX = has-metadata?(ECX, "imm32") +3237 # . . push args +3238 68/push "imm32"/imm32 +3239 51/push-ECX +3240 # . . call +3241 e8/call has-metadata?/disp32 +3242 # . . discard args +3243 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP +3244 # . if (EAX == 0) goto next check +3245 3d/compare-EAX-and 0/imm32 +3246 74/jump-if-equal $emit-imm:check-for-imm16/disp8 +3247 $emit-imm:imm32: +3248 # emit(out, word-slice, 4) +3249 # . . push args +3250 68/push 4/imm32 +3251 51/push-ECX +3252 ff 6/subop/push 1/mod/*+disp8 5/rm32/EBP . . . . 0xc/disp8 . # push *(EBP+12) +3253 # . . call +3254 e8/call emit/disp32 +3255 # . . discard args +3256 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP +3257 # break +3258 e9/jump $emit-imm:break/disp32 +3259 $emit-imm:check-for-imm16: +3260 # if (has-metadata?(word-slice, "imm16")) +3261 # . EAX = has-metadata?(ECX, "imm16") +3262 # . . push args +3263 68/push "imm16"/imm32 +3264 51/push-ECX +3265 # . . call +3266 e8/call has-metadata?/disp32 +3267 # . . discard args +3268 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP +3269 # . if (EAX == 0) goto next check +3270 3d/compare-EAX-and 0/imm32 +3271 74/jump-if-equal $emit-imm:check-for-imm8/disp8 +3272 $emit-imm:imm16: +3273 # emit(out, word-slice, 2) +3274 # . . push args +3275 68/push 2/imm32 +3276 51/push-ECX +3277 ff 6/subop/push 1/mod/*+disp8 5/rm32/EBP . . . . 0xc/disp8 . # push *(EBP+12) +3278 # . . call +3279 e8/call emit/disp32 +3280 # . . discard args +3281 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP +3282 # break +3283 e9/jump $emit-imm:break/disp32 +3284 $emit-imm:check-for-imm8: +3285 # if (has-metadata?(word-slice, "imm8")) +3286 # . EAX = has-metadata?(ECX, "imm8") +3287 # . . push args +3288 68/push "imm8"/imm32 +3289 51/push-ECX +3290 # . . call +3291 e8/call has-metadata?/disp32 +3292 # . . discard args +3293 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP +3294 # . if (EAX == 0) loop +3295 3d/compare-EAX-and 0/imm32 +3296 0f 84/jump-if-equal $emit-imm:loop/disp32 +3297 $emit-imm:imm8: +3298 # emit(out, word-slice, 1) +3299 # . . push args +3300 68/push 1/imm32 +3301 51/push-ECX +3302 ff 6/subop/push 1/mod/*+disp8 5/rm32/EBP . . . . 0xc/disp8 . # push *(EBP+12) +3303 # . . call +3304 e8/call emit/disp32 +3305 # . . discard args +3306 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP +3307 # break +3308 $emit-imm:break: +3309 # . restore locals +3310 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP +3311 # . restore registers +3312 5a/pop-to-EDX +3313 59/pop-to-ECX +3314 58/pop-to-EAX +3315 # . epilog +3316 89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . . # copy EBP to ESP +3317 5d/pop-to-EBP +3318 c3/return +3319 +3320 emit-line-in-comment: # line : (address stream byte), out : (address buffered-file) -> <void> +3321 # . prolog +3322 55/push-EBP +3323 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP +3324 # write-buffered(out, " # ") +3325 # . . push args +3326 68/push " # "/imm32 +3327 ff 6/subop/push 1/mod/*+disp8 5/rm32/EBP . . . . 0xc/disp8 . # push *(EBP+12) +3328 # . . call +3329 e8/call write-buffered/disp32 +3330 # . . discard args +3331 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP +3332 # write-stream-data(out, line) +3333 # . . push args +3334 ff 6/subop/push 1/mod/*+disp8 5/rm32/EBP . . . . 8/disp8 . # push *(EBP+8) +3335 ff 6/subop/push 1/mod/*+disp8 5/rm32/EBP . . . . 0xc/disp8 . # push *(EBP+12) +3336 # . . call +3337 e8/call write-stream-data/disp32 +3338 # . . discard args +3339 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP +3340 $emit-line-in-comment:end: +3341 # . epilog +3342 89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . . # copy EBP to ESP +3343 5d/pop-to-EBP +3344 c3/return +3345 +3346 test-convert-instruction-passes-comments-through: +3347 # if a line starts with '#', pass it along unchanged +3348 # . prolog +3349 55/push-EBP +3350 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP +3351 # setup +3352 # . clear-stream(_test-input-stream) +3353 # . . push args +3354 68/push _test-input-stream/imm32 +3355 # . . call +3356 e8/call clear-stream/disp32 +3357 # . . discard args +3358 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP +3359 # . clear-stream(_test-output-stream) +3360 # . . push args +3361 68/push _test-output-stream/imm32 +3362 # . . call +3363 e8/call clear-stream/disp32 +3364 # . . discard args +3365 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP +3366 # . clear-stream(_test-output-buffered-file+4) +3367 # . . push args +3368 b8/copy-to-EAX _test-output-buffered-file/imm32 +3369 05/add-to-EAX 4/imm32 +3370 50/push-EAX +3371 # . . call +3372 e8/call clear-stream/disp32 +3373 # . . discard args +3374 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP +3375 # initialize input +3376 # . write(_test-input-stream, "# abcd") +3377 # . . push args +3378 68/push "# abcd"/imm32 +3379 68/push _test-input-stream/imm32 +3380 # . . call +3381 e8/call write/disp32 +3382 # . . discard args +3383 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP +3384 # convert-instruction(_test-input-stream, _test-output-buffered-file) +3385 # . . push args +3386 68/push _test-output-buffered-file/imm32 +3387 68/push _test-input-stream/imm32 +3388 # . . call +3389 e8/call convert-instruction/disp32 +3390 # . . discard args +3391 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP +3392 # check that the line just passed through +3393 # . flush(_test-output-buffered-file) +3394 # . . push args +3395 68/push _test-output-buffered-file/imm32 +3396 # . . call +3397 e8/call flush/disp32 +3398 # . . discard args +3399 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP +3400 # . check-stream-equal(_test-output-stream, "# abcd", msg) +3401 # . . push args +3402 68/push "F - test-convert-instruction-passes-comments-through"/imm32 +3403 68/push "# abcd"/imm32 +3404 68/push _test-output-stream/imm32 +3405 # . . call +3406 e8/call check-stream-equal/disp32 +3407 # . . discard args +3408 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP +3409 # . epilog +3410 89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . . # copy EBP to ESP +3411 5d/pop-to-EBP +3412 c3/return +3413 +3414 test-convert-instruction-passes-labels-through: +3415 # if the first word ends with ':', pass along the entire line unchanged +3416 # . prolog +3417 55/push-EBP +3418 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP +3419 # setup +3420 # . clear-stream(_test-input-stream) +3421 # . . push args +3422 68/push _test-input-stream/imm32 +3423 # . . call +3424 e8/call clear-stream/disp32 +3425 # . . discard args +3426 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP +3427 # . clear-stream(_test-output-stream) +3428 # . . push args +3429 68/push _test-output-stream/imm32 +3430 # . . call +3431 e8/call clear-stream/disp32 +3432 # . . discard args +3433 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP +3434 # . clear-stream(_test-output-buffered-file+4) +3435 # . . push args +3436 b8/copy-to-EAX _test-output-buffered-file/imm32 +3437 05/add-to-EAX 4/imm32 +3438 50/push-EAX +3439 # . . call +3440 e8/call clear-stream/disp32 +3441 # . . discard args +3442 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP +3443 # initialize input +3444 # . write(_test-input-stream, "ab: # cd") 3445 # . . push args -3446 68/push "imm32"/imm32 -3447 51/push-ECX +3446 68/push "ab: # cd"/imm32 +3447 68/push _test-input-stream/imm32 3448 # . . call -3449 e8/call has-metadata?/disp32 +3449 e8/call write/disp32 3450 # . . discard args 3451 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP -3452 # . if (EAX == 0) goto next check -3453 3d/compare-EAX-and 0/imm32 -3454 74/jump-if-equal $emit-imm:check-for-imm16/disp8 -3455 $emit-imm:imm32: -3456 # emit(out, word-slice, 4) -3457 # . . push args -3458 68/push 4/imm32 -3459 51/push-ECX -3460 ff 6/subop/push 1/mod/*+disp8 5/rm32/EBP . . . . 0xc/disp8 . # push *(EBP+12) -3461 # . . call -3462 e8/call emit/disp32 -3463 # . . discard args -3464 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP -3465 # break -3466 e9/jump $emit-imm:break/disp32 -3467 $emit-imm:check-for-imm16: -3468 # if (has-metadata?(word-slice, "imm16")) -3469 # . EAX = has-metadata?(ECX, "imm16") -3470 # . . push args -3471 68/push "imm16"/imm32 -3472 51/push-ECX +3452 # convert-instruction(_test-input-stream, _test-output-buffered-file) +3453 # . . push args +3454 68/push _test-output-buffered-file/imm32 +3455 68/push _test-input-stream/imm32 +3456 # . . call +3457 e8/call convert-instruction/disp32 +3458 # . . discard args +3459 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP +3460 # check that the line just passed through +3461 # . flush(_test-output-buffered-file) +3462 # . . push args +3463 68/push _test-output-buffered-file/imm32 +3464 # . . call +3465 e8/call flush/disp32 +3466 # . . discard args +3467 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP +3468 # . check-stream-equal(_test-output-stream, "ab: # cd", msg) +3469 # . . push args +3470 68/push "F - test-convert-instruction-passes-labels-through"/imm32 +3471 68/push "ab: # cd"/imm32 +3472 68/push _test-output-stream/imm32 3473 # . . call -3474 e8/call has-metadata?/disp32 +3474 e8/call check-stream-equal/disp32 3475 # . . discard args -3476 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP -3477 # . if (EAX == 0) goto next check -3478 3d/compare-EAX-and 0/imm32 -3479 74/jump-if-equal $emit-imm:check-for-imm8/disp8 -3480 $emit-imm:imm16: -3481 # emit(out, word-slice, 2) -3482 # . . push args -3483 68/push 2/imm32 -3484 51/push-ECX -3485 ff 6/subop/push 1/mod/*+disp8 5/rm32/EBP . . . . 0xc/disp8 . # push *(EBP+12) -3486 # . . call -3487 e8/call emit/disp32 -3488 # . . discard args -3489 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP -3490 # break -3491 e9/jump $emit-imm:break/disp32 -3492 $emit-imm:check-for-imm8: -3493 # if (has-metadata?(word-slice, "imm8")) -3494 # . EAX = has-metadata?(ECX, "imm8") -3495 # . . push args -3496 68/push "imm8"/imm32 -3497 51/push-ECX +3476 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP +3477 # . epilog +3478 89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . . # copy EBP to ESP +3479 5d/pop-to-EBP +3480 c3/return +3481 +3482 test-convert-instruction-handles-single-opcode: +3483 # if the instruction consists of a single opcode, strip its metadata and pass it along +3484 # . prolog +3485 55/push-EBP +3486 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP +3487 # setup +3488 # . clear-stream(_test-input-stream) +3489 # . . push args +3490 68/push _test-input-stream/imm32 +3491 # . . call +3492 e8/call clear-stream/disp32 +3493 # . . discard args +3494 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP +3495 # . clear-stream(_test-output-stream) +3496 # . . push args +3497 68/push _test-output-stream/imm32 3498 # . . call -3499 e8/call has-metadata?/disp32 +3499 e8/call clear-stream/disp32 3500 # . . discard args -3501 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP -3502 # . if (EAX == 0) loop -3503 3d/compare-EAX-and 0/imm32 -3504 0f 84/jump-if-equal $emit-imm:loop/disp32 -3505 $emit-imm:imm8: -3506 # emit(out, word-slice, 1) -3507 # . . push args -3508 68/push 1/imm32 -3509 51/push-ECX -3510 ff 6/subop/push 1/mod/*+disp8 5/rm32/EBP . . . . 0xc/disp8 . # push *(EBP+12) -3511 # . . call -3512 e8/call emit/disp32 -3513 # . . discard args -3514 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP -3515 # break -3516 $emit-imm:break: -3517 # . restore locals -3518 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP -3519 # . restore registers -3520 5a/pop-to-EDX -3521 59/pop-to-ECX -3522 58/pop-to-EAX -3523 # . epilog -3524 89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . . # copy EBP to ESP -3525 5d/pop-to-EBP -3526 c3/return -3527 -3528 emit-line-in-comment: # line : (address stream byte), out : (address buffered-file) -> <void> -3529 # . prolog -3530 55/push-EBP -3531 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP -3532 # write-buffered(out, " # ") -3533 # . . push args -3534 68/push " # "/imm32 -3535 ff 6/subop/push 1/mod/*+disp8 5/rm32/EBP . . . . 0xc/disp8 . # push *(EBP+12) -3536 # . . call -3537 e8/call write-buffered/disp32 -3538 # . . discard args -3539 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP -3540 # write-stream-data(out, line) -3541 # . . push args -3542 ff 6/subop/push 1/mod/*+disp8 5/rm32/EBP . . . . 8/disp8 . # push *(EBP+8) -3543 ff 6/subop/push 1/mod/*+disp8 5/rm32/EBP . . . . 0xc/disp8 . # push *(EBP+12) -3544 # . . call -3545 e8/call write-stream-data/disp32 -3546 # . . discard args -3547 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP -3548 $emit-line-in-comment:end: -3549 # . epilog -3550 89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . . # copy EBP to ESP -3551 5d/pop-to-EBP -3552 c3/return -3553 -3554 test-convert-instruction-passes-comments-through: -3555 # if a line starts with '#', pass it along unchanged -3556 # . prolog -3557 55/push-EBP -3558 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP -3559 # setup -3560 # . clear-stream(_test-input-stream) -3561 # . . push args -3562 68/push _test-input-stream/imm32 -3563 # . . call -3564 e8/call clear-stream/disp32 -3565 # . . discard args -3566 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP -3567 # . clear-stream(_test-output-stream) -3568 # . . push args -3569 68/push _test-output-stream/imm32 -3570 # . . call -3571 e8/call clear-stream/disp32 -3572 # . . discard args -3573 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP -3574 # . clear-stream(_test-output-buffered-file+4) -3575 # . . push args -3576 b8/copy-to-EAX _test-output-buffered-file/imm32 -3577 05/add-to-EAX 4/imm32 -3578 50/push-EAX -3579 # . . call -3580 e8/call clear-stream/disp32 -3581 # . . discard args -3582 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP -3583 # initialize input -3584 # . write(_test-input-stream, "# abcd") -3585 # . . push args -3586 68/push "# abcd"/imm32 -3587 68/push _test-input-stream/imm32 -3588 # . . call -3589 e8/call write/disp32 -3590 # . . discard args -3591 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP -3592 # convert-instruction(_test-input-stream, _test-output-buffered-file) -3593 # . . push args -3594 68/push _test-output-buffered-file/imm32 -3595 68/push _test-input-stream/imm32 -3596 # . . call -3597 e8/call convert-instruction/disp32 -3598 # . . discard args -3599 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP -3600 # check that the line just passed through -3601 # . flush(_test-output-buffered-file) -3602 # . . push args -3603 68/push _test-output-buffered-file/imm32 -3604 # . . call -3605 e8/call flush/disp32 -3606 # . . discard args -3607 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP -3608 # . check-stream-equal(_test-output-stream, "# abcd", msg) -3609 # . . push args -3610 68/push "F - test-convert-instruction-passes-comments-through"/imm32 -3611 68/push "# abcd"/imm32 -3612 68/push _test-output-stream/imm32 -3613 # . . call -3614 e8/call check-stream-equal/disp32 -3615 # . . discard args -3616 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP -3617 # . epilog -3618 89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . . # copy EBP to ESP -3619 5d/pop-to-EBP -3620 c3/return -3621 -3622 test-convert-instruction-passes-labels-through: -3623 # if the first word ends with ':', pass along the entire line unchanged -3624 # . prolog -3625 55/push-EBP -3626 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP -3627 # setup -3628 # . clear-stream(_test-input-stream) -3629 # . . push args -3630 68/push _test-input-stream/imm32 -3631 # . . call -3632 e8/call clear-stream/disp32 -3633 # . . discard args -3634 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP -3635 # . clear-stream(_test-output-stream) -3636 # . . push args -3637 68/push _test-output-stream/imm32 -3638 # . . call -3639 e8/call clear-stream/disp32 -3640 # . . discard args -3641 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP -3642 # . clear-stream(_test-output-buffered-file+4) -3643 # . . push args -3644 b8/copy-to-EAX _test-output-buffered-file/imm32 -3645 05/add-to-EAX 4/imm32 -3646 50/push-EAX -3647 # . . call -3648 e8/call clear-stream/disp32 -3649 # . . discard args -3650 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP -3651 # initialize input -3652 # . write(_test-input-stream, "ab: # cd") -3653 # . . push args -3654 68/push "ab: # cd"/imm32 -3655 68/push _test-input-stream/imm32 -3656 # . . call -3657 e8/call write/disp32 -3658 # . . discard args -3659 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP -3660 # convert-instruction(_test-input-stream, _test-output-buffered-file) -3661 # . . push args -3662 68/push _test-output-buffered-file/imm32 -3663 68/push _test-input-stream/imm32 -3664 # . . call -3665 e8/call convert-instruction/disp32 -3666 # . . discard args -3667 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP -3668 # check that the line just passed through -3669 # . flush(_test-output-buffered-file) -3670 # . . push args -3671 68/push _test-output-buffered-file/imm32 -3672 # . . call -3673 e8/call flush/disp32 -3674 # . . discard args -3675 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP -3676 # . check-stream-equal(_test-output-stream, "ab: # cd", msg) +3501 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP +3502 # . clear-stream(_test-output-buffered-file+4) +3503 # . . push args +3504 b8/copy-to-EAX _test-output-buffered-file/imm32 +3505 05/add-to-EAX 4/imm32 +3506 50/push-EAX +3507 # . . call +3508 e8/call clear-stream/disp32 +3509 # . . discard args +3510 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP +3511 # initialize input +3512 # . write(_test-input-stream, "ab/cd # comment") +3513 # . . push args +3514 68/push "ab/cd # comment"/imm32 +3515 68/push _test-input-stream/imm32 +3516 # . . call +3517 e8/call write/disp32 +3518 # . . discard args +3519 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP +3520 # convert-instruction(_test-input-stream, _test-output-buffered-file) +3521 # . . push args +3522 68/push _test-output-buffered-file/imm32 +3523 68/push _test-input-stream/imm32 +3524 # . . call +3525 e8/call convert-instruction/disp32 +3526 # . . discard args +3527 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP +3528 # check output +3529 # . flush(_test-output-buffered-file) +3530 # . . push args +3531 68/push _test-output-buffered-file/imm32 +3532 # . . call +3533 e8/call flush/disp32 +3534 # . . discard args +3535 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP +3536 +-- 26 lines: #? # dump output --------------------------------------------------------------------------------------------------------------------------- +3562 # . check-stream-equal(_test-output-stream, "ab # ab/cd # comment", msg) +3563 # . . push args +3564 68/push "F - test-convert-instruction-handles-single-opcode"/imm32 +3565 68/push "ab # ab/cd # comment"/imm32 +3566 68/push _test-output-stream/imm32 +3567 # . . call +3568 e8/call check-stream-equal/disp32 +3569 # . . discard args +3570 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP +3571 # . epilog +3572 89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . . # copy EBP to ESP +3573 5d/pop-to-EBP +3574 c3/return +3575 +3576 test-convert-instruction-handles-0f-opcode: +3577 # if the instruction starts with 0f opcode, include a second opcode +3578 # . prolog +3579 55/push-EBP +3580 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP +3581 # setup +3582 # . clear-stream(_test-input-stream) +3583 # . . push args +3584 68/push _test-input-stream/imm32 +3585 # . . call +3586 e8/call clear-stream/disp32 +3587 # . . discard args +3588 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP +3589 # . clear-stream(_test-output-stream) +3590 # . . push args +3591 68/push _test-output-stream/imm32 +3592 # . . call +3593 e8/call clear-stream/disp32 +3594 # . . discard args +3595 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP +3596 # . clear-stream(_test-output-buffered-file+4) +3597 # . . push args +3598 b8/copy-to-EAX _test-output-buffered-file/imm32 +3599 05/add-to-EAX 4/imm32 +3600 50/push-EAX +3601 # . . call +3602 e8/call clear-stream/disp32 +3603 # . . discard args +3604 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP +3605 # initialize input +3606 # . write(_test-input-stream, "0f/m1 ab/m2 # comment") +3607 # . . push args +3608 68/push "0f/m1 ab/m2 # comment"/imm32 +3609 68/push _test-input-stream/imm32 +3610 # . . call +3611 e8/call write/disp32 +3612 # . . discard args +3613 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP +3614 # convert-instruction(_test-input-stream, _test-output-buffered-file) +3615 # . . push args +3616 68/push _test-output-buffered-file/imm32 +3617 68/push _test-input-stream/imm32 +3618 # . . call +3619 e8/call convert-instruction/disp32 +3620 # . . discard args +3621 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP +3622 # check output +3623 # . flush(_test-output-buffered-file) +3624 # . . push args +3625 68/push _test-output-buffered-file/imm32 +3626 # . . call +3627 e8/call flush/disp32 +3628 # . . discard args +3629 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP +3630 +-- 26 lines: #? # dump output --------------------------------------------------------------------------------------------------------------------------- +3656 # . check-stream-equal(_test-output-stream, "0f ab # 0f/m1 ab/m2 # comment", msg) +3657 # . . push args +3658 68/push "F - test-convert-instruction-handles-0f-opcode"/imm32 +3659 68/push "0f ab # 0f/m1 ab/m2 # comment"/imm32 +3660 68/push _test-output-stream/imm32 +3661 # . . call +3662 e8/call check-stream-equal/disp32 +3663 # . . discard args +3664 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP +3665 # . epilog +3666 89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . . # copy EBP to ESP +3667 5d/pop-to-EBP +3668 c3/return +3669 +3670 test-convert-instruction-handles-f2-opcode: +3671 # if the instruction starts with f2 opcode, include a second opcode +3672 # . prolog +3673 55/push-EBP +3674 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP +3675 # setup +3676 # . clear-stream(_test-input-stream) 3677 # . . push args -3678 68/push "F - test-convert-instruction-passes-labels-through"/imm32 -3679 68/push "ab: # cd"/imm32 -3680 68/push _test-output-stream/imm32 -3681 # . . call -3682 e8/call check-stream-equal/disp32 -3683 # . . discard args -3684 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP -3685 # . epilog -3686 89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . . # copy EBP to ESP -3687 5d/pop-to-EBP -3688 c3/return -3689 -3690 test-convert-instruction-handles-single-opcode: -3691 # if the instruction consists of a single opcode, strip its metadata and pass it along -3692 # . prolog -3693 55/push-EBP -3694 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP -3695 # setup -3696 # . clear-stream(_test-input-stream) -3697 # . . push args -3698 68/push _test-input-stream/imm32 -3699 # . . call -3700 e8/call clear-stream/disp32 -3701 # . . discard args -3702 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP -3703 # . clear-stream(_test-output-stream) -3704 # . . push args -3705 68/push _test-output-stream/imm32 -3706 # . . call -3707 e8/call clear-stream/disp32 -3708 # . . discard args -3709 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP -3710 # . clear-stream(_test-output-buffered-file+4) -3711 # . . push args -3712 b8/copy-to-EAX _test-output-buffered-file/imm32 -3713 05/add-to-EAX 4/imm32 -3714 50/push-EAX -3715 # . . call -3716 e8/call clear-stream/disp32 -3717 # . . discard args -3718 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP -3719 # initialize input -3720 # . write(_test-input-stream, "ab/cd # comment") -3721 # . . push args -3722 68/push "ab/cd # comment"/imm32 -3723 68/push _test-input-stream/imm32 -3724 # . . call -3725 e8/call write/disp32 -3726 # . . discard args -3727 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP -3728 # convert-instruction(_test-input-stream, _test-output-buffered-file) -3729 # . . push args -3730 68/push _test-output-buffered-file/imm32 -3731 68/push _test-input-stream/imm32 -3732 # . . call -3733 e8/call convert-instruction/disp32 -3734 # . . discard args -3735 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP -3736 # check output -3737 # . flush(_test-output-buffered-file) -3738 # . . push args -3739 68/push _test-output-buffered-file/imm32 -3740 # . . call -3741 e8/call flush/disp32 -3742 # . . discard args -3743 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP -3744 +-- 34 lines: #? # dump output --------------------------------------------------------------------------------------------------------------------------- -3778 # . check-stream-equal(_test-output-stream, "ab # ab/cd # comment", msg) -3779 # . . push args -3780 68/push "F - test-convert-instruction-handles-single-opcode"/imm32 -3781 68/push "ab # ab/cd # comment"/imm32 -3782 68/push _test-output-stream/imm32 -3783 # . . call -3784 e8/call check-stream-equal/disp32 -3785 # . . discard args -3786 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP -3787 # . epilog -3788 89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . . # copy EBP to ESP -3789 5d/pop-to-EBP -3790 c3/return -3791 -3792 test-convert-instruction-handles-0f-opcode: -3793 # if the instruction starts with 0f opcode, include a second opcode -3794 # . prolog -3795 55/push-EBP -3796 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP -3797 # setup -3798 # . clear-stream(_test-input-stream) -3799 # . . push args -3800 68/push _test-input-stream/imm32 -3801 # . . call -3802 e8/call clear-stream/disp32 -3803 # . . discard args -3804 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP -3805 # . clear-stream(_test-output-stream) -3806 # . . push args -3807 68/push _test-output-stream/imm32 -3808 # . . call -3809 e8/call clear-stream/disp32 -3810 # . . discard args -3811 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP -3812 # . clear-stream(_test-output-buffered-file+4) -3813 # . . push args -3814 b8/copy-to-EAX _test-output-buffered-file/imm32 -3815 05/add-to-EAX 4/imm32 -3816 50/push-EAX -3817 # . . call -3818 e8/call clear-stream/disp32 -3819 # . . discard args -3820 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP -3821 # initialize input -3822 # . write(_test-input-stream, "0f/m1 ab/m2 # comment") -3823 # . . push args -3824 68/push "0f/m1 ab/m2 # comment"/imm32 -3825 68/push _test-input-stream/imm32 -3826 # . . call -3827 e8/call write/disp32 -3828 # . . discard args -3829 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP -3830 # convert-instruction(_test-input-stream, _test-output-buffered-file) -3831 # . . push args -3832 68/push _test-output-buffered-file/imm32 -3833 68/push _test-input-stream/imm32 -3834 # . . call -3835 e8/call convert-instruction/disp32 -3836 # . . discard args -3837 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP -3838 # check output -3839 # . flush(_test-output-buffered-file) -3840 # . . push args -3841 68/push _test-output-buffered-file/imm32 -3842 # . . call -3843 e8/call flush/disp32 -3844 # . . discard args -3845 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP -3846 +-- 34 lines: #? # dump output --------------------------------------------------------------------------------------------------------------------------- -3880 # . check-stream-equal(_test-output-stream, "0f ab # 0f/m1 ab/m2 # comment", msg) -3881 # . . push args -3882 68/push "F - test-convert-instruction-handles-0f-opcode"/imm32 -3883 68/push "0f ab # 0f/m1 ab/m2 # comment"/imm32 -3884 68/push _test-output-stream/imm32 -3885 # . . call -3886 e8/call check-stream-equal/disp32 -3887 # . . discard args -3888 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP -3889 # . epilog -3890 89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . . # copy EBP to ESP -3891 5d/pop-to-EBP -3892 c3/return -3893 -3894 test-convert-instruction-handles-f2-opcode: -3895 # if the instruction starts with f2 opcode, include a second opcode -3896 # . prolog -3897 55/push-EBP -3898 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP -3899 # setup -3900 # . clear-stream(_test-input-stream) -3901 # . . push args -3902 68/push _test-input-stream/imm32 -3903 # . . call -3904 e8/call clear-stream/disp32 -3905 # . . discard args -3906 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP -3907 # . clear-stream(_test-output-stream) -3908 # . . push args -3909 68/push _test-output-stream/imm32 -3910 # . . call -3911 e8/call clear-stream/disp32 -3912 # . . discard args -3913 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP -3914 # . clear-stream(_test-output-buffered-file+4) -3915 # . . push args -3916 b8/copy-to-EAX _test-output-buffered-file/imm32 -3917 05/add-to-EAX 4/imm32 -3918 50/push-EAX -3919 # . . call -3920 e8/call clear-stream/disp32 -3921 # . . discard args -3922 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP -3923 # initialize input -3924 # . write(_test-input-stream, "f2/m1 ab/m2 # comment") -3925 # . . push args -3926 68/push "f2/m1 ab/m2 # comment"/imm32 -3927 68/push _test-input-stream/imm32 -3928 # . . call -3929 e8/call write/disp32 -3930 # . . discard args -3931 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP -3932 # convert-instruction(_test-input-stream, _test-output-buffered-file) -3933 # . . push args -3934 68/push _test-output-buffered-file/imm32 -3935 68/push _test-input-stream/imm32 -3936 # . . call -3937 e8/call convert-instruction/disp32 -3938 # . . discard args -3939 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP -3940 # check output -3941 # . flush(_test-output-buffered-file) -3942 # . . push args -3943 68/push _test-output-buffered-file/imm32 -3944 # . . call -3945 e8/call flush/disp32 -3946 # . . discard args -3947 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP -3948 +-- 34 lines: #? # dump output --------------------------------------------------------------------------------------------------------------------------- -3982 # . check-stream-equal(_test-output-stream, "f2 ab # f2/m1 ab/m2 # comment", msg) +3678 68/push _test-input-stream/imm32 +3679 # . . call +3680 e8/call clear-stream/disp32 +3681 # . . discard args +3682 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP +3683 # . clear-stream(_test-output-stream) +3684 # . . push args +3685 68/push _test-output-stream/imm32 +3686 # . . call +3687 e8/call clear-stream/disp32 +3688 # . . discard args +3689 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP +3690 # . clear-stream(_test-output-buffered-file+4) +3691 # . . push args +3692 b8/copy-to-EAX _test-output-buffered-file/imm32 +3693 05/add-to-EAX 4/imm32 +3694 50/push-EAX +3695 # . . call +3696 e8/call clear-stream/disp32 +3697 # . . discard args +3698 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP +3699 # initialize input +3700 # . write(_test-input-stream, "f2/m1 ab/m2 # comment") +3701 # . . push args +3702 68/push "f2/m1 ab/m2 # comment"/imm32 +3703 68/push _test-input-stream/imm32 +3704 # . . call +3705 e8/call write/disp32 +3706 # . . discard args +3707 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP +3708 # convert-instruction(_test-input-stream, _test-output-buffered-file) +3709 # . . push args +3710 68/push _test-output-buffered-file/imm32 +3711 68/push _test-input-stream/imm32 +3712 # . . call +3713 e8/call convert-instruction/disp32 +3714 # . . discard args +3715 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP +3716 # check output +3717 # . flush(_test-output-buffered-file) +3718 # . . push args +3719 68/push _test-output-buffered-file/imm32 +3720 # . . call +3721 e8/call flush/disp32 +3722 # . . discard args +3723 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP +3724 +-- 26 lines: #? # dump output --------------------------------------------------------------------------------------------------------------------------- +3750 # . check-stream-equal(_test-output-stream, "f2 ab # f2/m1 ab/m2 # comment", msg) +3751 # . . push args +3752 68/push "F - test-convert-instruction-handles-f2-opcode"/imm32 +3753 68/push "f2 ab # f2/m1 ab/m2 # comment"/imm32 +3754 68/push _test-output-stream/imm32 +3755 # . . call +3756 e8/call check-stream-equal/disp32 +3757 # . . discard args +3758 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP +3759 # . epilog +3760 89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . . # copy EBP to ESP +3761 5d/pop-to-EBP +3762 c3/return +3763 +3764 test-convert-instruction-handles-f3-opcode: +3765 # if the instruction starts with f3 opcode, include a second opcode +3766 # . prolog +3767 55/push-EBP +3768 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP +3769 # setup +3770 # . clear-stream(_test-input-stream) +3771 # . . push args +3772 68/push _test-input-stream/imm32 +3773 # . . call +3774 e8/call clear-stream/disp32 +3775 # . . discard args +3776 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP +3777 # . clear-stream(_test-output-stream) +3778 # . . push args +3779 68/push _test-output-stream/imm32 +3780 # . . call +3781 e8/call clear-stream/disp32 +3782 # . . discard args +3783 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP +3784 # . clear-stream(_test-output-buffered-file+4) +3785 # . . push args +3786 b8/copy-to-EAX _test-output-buffered-file/imm32 +3787 05/add-to-EAX 4/imm32 +3788 50/push-EAX +3789 # . . call +3790 e8/call clear-stream/disp32 +3791 # . . discard args +3792 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP +3793 # initialize input +3794 # . write(_test-input-stream, "f3/m1 ab/m2 # comment") +3795 # . . push args +3796 68/push "f3/m1 ab/m2 # comment"/imm32 +3797 68/push _test-input-stream/imm32 +3798 # . . call +3799 e8/call write/disp32 +3800 # . . discard args +3801 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP +3802 # convert-instruction(_test-input-stream, _test-output-buffered-file) +3803 # . . push args +3804 68/push _test-output-buffered-file/imm32 +3805 68/push _test-input-stream/imm32 +3806 # . . call +3807 e8/call convert-instruction/disp32 +3808 # . . discard args +3809 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP +3810 # check output +3811 # . flush(_test-output-buffered-file) +3812 # . . push args +3813 68/push _test-output-buffered-file/imm32 +3814 # . . call +3815 e8/call flush/disp32 +3816 # . . discard args +3817 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP +3818 +-- 26 lines: #? # dump output --------------------------------------------------------------------------------------------------------------------------- +3844 # . check-stream-equal(_test-output-stream, "f3 ab # f3/m1 ab/m2 # comment", msg) +3845 # . . push args +3846 68/push "F - test-convert-instruction-handles-f3-opcode"/imm32 +3847 68/push "f3 ab # f3/m1 ab/m2 # comment"/imm32 +3848 68/push _test-output-stream/imm32 +3849 # . . call +3850 e8/call check-stream-equal/disp32 +3851 # . . discard args +3852 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP +3853 # . epilog +3854 89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . . # copy EBP to ESP +3855 5d/pop-to-EBP +3856 c3/return +3857 +3858 test-convert-instruction-handles-f2-0f-opcode: +3859 # if the instruction starts with f2 0f opcode, include a second opcode +3860 # . prolog +3861 55/push-EBP +3862 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP +3863 # setup +3864 # . clear-stream(_test-input-stream) +3865 # . . push args +3866 68/push _test-input-stream/imm32 +3867 # . . call +3868 e8/call clear-stream/disp32 +3869 # . . discard args +3870 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP +3871 # . clear-stream(_test-output-stream) +3872 # . . push args +3873 68/push _test-output-stream/imm32 +3874 # . . call +3875 e8/call clear-stream/disp32 +3876 # . . discard args +3877 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP +3878 # . clear-stream(_test-output-buffered-file+4) +3879 # . . push args +3880 b8/copy-to-EAX _test-output-buffered-file/imm32 +3881 05/add-to-EAX 4/imm32 +3882 50/push-EAX +3883 # . . call +3884 e8/call clear-stream/disp32 +3885 # . . discard args +3886 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP +3887 # initialize input +3888 # . write(_test-input-stream, "f2/m1 0f/m2 ab/m3 # comment") +3889 # . . push args +3890 68/push "f2/m1 0f/m2 ab/m3 # comment"/imm32 +3891 68/push _test-input-stream/imm32 +3892 # . . call +3893 e8/call write/disp32 +3894 # . . discard args +3895 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP +3896 # convert-instruction(_test-input-stream, _test-output-buffered-file) +3897 # . . push args +3898 68/push _test-output-buffered-file/imm32 +3899 68/push _test-input-stream/imm32 +3900 # . . call +3901 e8/call convert-instruction/disp32 +3902 # . . discard args +3903 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP +3904 # check output +3905 # . flush(_test-output-buffered-file) +3906 # . . push args +3907 68/push _test-output-buffered-file/imm32 +3908 # . . call +3909 e8/call flush/disp32 +3910 # . . discard args +3911 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP +3912 +-- 26 lines: #? # dump output --------------------------------------------------------------------------------------------------------------------------- +3938 # . check-stream-equal(_test-output-stream, "f2 0f ab # f2/m1 0f/m2 ab/m3 # comment", msg) +3939 # . . push args +3940 68/push "F - test-convert-instruction-handles-f2-0f-opcode"/imm32 +3941 68/push "f2 0f ab # f2/m1 0f/m2 ab/m3 # comment"/imm32 +3942 68/push _test-output-stream/imm32 +3943 # . . call +3944 e8/call check-stream-equal/disp32 +3945 # . . discard args +3946 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP +3947 # . epilog +3948 89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . . # copy EBP to ESP +3949 5d/pop-to-EBP +3950 c3/return +3951 +3952 test-convert-instruction-handles-f3-0f-opcode: +3953 # if the instruction starts with f3 0f opcode, include a second opcode +3954 # . prolog +3955 55/push-EBP +3956 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP +3957 # setup +3958 # . clear-stream(_test-input-stream) +3959 # . . push args +3960 68/push _test-input-stream/imm32 +3961 # . . call +3962 e8/call clear-stream/disp32 +3963 # . . discard args +3964 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP +3965 # . clear-stream(_test-output-stream) +3966 # . . push args +3967 68/push _test-output-stream/imm32 +3968 # . . call +3969 e8/call clear-stream/disp32 +3970 # . . discard args +3971 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP +3972 # . clear-stream(_test-output-buffered-file+4) +3973 # . . push args +3974 b8/copy-to-EAX _test-output-buffered-file/imm32 +3975 05/add-to-EAX 4/imm32 +3976 50/push-EAX +3977 # . . call +3978 e8/call clear-stream/disp32 +3979 # . . discard args +3980 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP +3981 # initialize input +3982 # . write(_test-input-stream, "f3/m1 0f/m2 ab/m3 # comment") 3983 # . . push args -3984 68/push "F - test-convert-instruction-handles-f2-opcode"/imm32 -3985 68/push "f2 ab # f2/m1 ab/m2 # comment"/imm32 -3986 68/push _test-output-stream/imm32 -3987 # . . call -3988 e8/call check-stream-equal/disp32 -3989 # . . discard args -3990 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP -3991 # . epilog -3992 89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . . # copy EBP to ESP -3993 5d/pop-to-EBP -3994 c3/return -3995 -3996 test-convert-instruction-handles-f3-opcode: -3997 # if the instruction starts with f3 opcode, include a second opcode -3998 # . prolog -3999 55/push-EBP -4000 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP -4001 # setup -4002 # . clear-stream(_test-input-stream) -4003 # . . push args -4004 68/push _test-input-stream/imm32 -4005 # . . call -4006 e8/call clear-stream/disp32 -4007 # . . discard args -4008 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP -4009 # . clear-stream(_test-output-stream) -4010 # . . push args -4011 68/push _test-output-stream/imm32 -4012 # . . call -4013 e8/call clear-stream/disp32 -4014 # . . discard args -4015 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP -4016 # . clear-stream(_test-output-buffered-file+4) -4017 # . . push args -4018 b8/copy-to-EAX _test-output-buffered-file/imm32 -4019 05/add-to-EAX 4/imm32 -4020 50/push-EAX -4021 # . . call -4022 e8/call clear-stream/disp32 -4023 # . . discard args -4024 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP -4025 # initialize input -4026 # . write(_test-input-stream, "f3/m1 ab/m2 # comment") -4027 # . . push args -4028 68/push "f3/m1 ab/m2 # comment"/imm32 -4029 68/push _test-input-stream/imm32 -4030 # . . call -4031 e8/call write/disp32 -4032 # . . discard args -4033 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP -4034 # convert-instruction(_test-input-stream, _test-output-buffered-file) -4035 # . . push args -4036 68/push _test-output-buffered-file/imm32 -4037 68/push _test-input-stream/imm32 -4038 # . . call -4039 e8/call convert-instruction/disp32 -4040 # . . discard args -4041 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP -4042 # check output -4043 # . flush(_test-output-buffered-file) -4044 # . . push args -4045 68/push _test-output-buffered-file/imm32 -4046 # . . call -4047 e8/call flush/disp32 -4048 # . . discard args -4049 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP -4050 +-- 34 lines: #? # dump output --------------------------------------------------------------------------------------------------------------------------- -4084 # . check-stream-equal(_test-output-stream, "f3 ab # f3/m1 ab/m2 # comment", msg) +3984 68/push "f3/m1 0f/m2 ab/m3 # comment"/imm32 +3985 68/push _test-input-stream/imm32 +3986 # . . call +3987 e8/call write/disp32 +3988 # . . discard args +3989 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP +3990 # convert-instruction(_test-input-stream, _test-output-buffered-file) +3991 # . . push args +3992 68/push _test-output-buffered-file/imm32 +3993 68/push _test-input-stream/imm32 +3994 # . . call +3995 e8/call convert-instruction/disp32 +3996 # . . discard args +3997 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP +3998 # check output +3999 # . flush(_test-output-buffered-file) +4000 # . . push args +4001 68/push _test-output-buffered-file/imm32 +4002 # . . call +4003 e8/call flush/disp32 +4004 # . . discard args +4005 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP +4006 +-- 26 lines: #? # dump output --------------------------------------------------------------------------------------------------------------------------- +4032 # . check-stream-equal(_test-output-stream, "f3 0f ab # f3/m1 0f/m2 ab/m3 # comment", msg) +4033 # . . push args +4034 68/push "F - test-convert-instruction-handles-f3-0f-opcode"/imm32 +4035 68/push "f3 0f ab # f3/m1 0f/m2 ab/m3 # comment"/imm32 +4036 68/push _test-output-stream/imm32 +4037 # . . call +4038 e8/call check-stream-equal/disp32 +4039 # . . discard args +4040 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP +4041 # . epilog +4042 89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . . # copy EBP to ESP +4043 5d/pop-to-EBP +4044 c3/return +4045 +4046 test-convert-instruction-handles-unused-opcodes: +4047 # if the instruction doesn't start with f2, f3 or 0f, don't include other opcodes +4048 # . prolog +4049 55/push-EBP +4050 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP +4051 # setup +4052 # . clear-stream(_test-input-stream) +4053 # . . push args +4054 68/push _test-input-stream/imm32 +4055 # . . call +4056 e8/call clear-stream/disp32 +4057 # . . discard args +4058 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP +4059 # . clear-stream(_test-output-stream) +4060 # . . push args +4061 68/push _test-output-stream/imm32 +4062 # . . call +4063 e8/call clear-stream/disp32 +4064 # . . discard args +4065 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP +4066 # . clear-stream(_test-output-buffered-file+4) +4067 # . . push args +4068 b8/copy-to-EAX _test-output-buffered-file/imm32 +4069 05/add-to-EAX 4/imm32 +4070 50/push-EAX +4071 # . . call +4072 e8/call clear-stream/disp32 +4073 # . . discard args +4074 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP +4075 # initialize input +4076 # . write(_test-input-stream, "ab/m1 cd/m2 # comment") +4077 # . . push args +4078 68/push "ab/m1 cd/m2 # comment"/imm32 +4079 68/push _test-input-stream/imm32 +4080 # . . call +4081 e8/call write/disp32 +4082 # . . discard args +4083 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP +4084 # convert-instruction(_test-input-stream, _test-output-buffered-file) 4085 # . . push args -4086 68/push "F - test-convert-instruction-handles-f3-opcode"/imm32 -4087 68/push "f3 ab # f3/m1 ab/m2 # comment"/imm32 -4088 68/push _test-output-stream/imm32 -4089 # . . call -4090 e8/call check-stream-equal/disp32 -4091 # . . discard args -4092 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP -4093 # . epilog -4094 89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . . # copy EBP to ESP -4095 5d/pop-to-EBP -4096 c3/return -4097 -4098 test-convert-instruction-handles-f2-0f-opcode: -4099 # if the instruction starts with f2 0f opcode, include a second opcode -4100 # . prolog -4101 55/push-EBP -4102 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP -4103 # setup -4104 # . clear-stream(_test-input-stream) -4105 # . . push args -4106 68/push _test-input-stream/imm32 -4107 # . . call -4108 e8/call clear-stream/disp32 -4109 # . . discard args -4110 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP -4111 # . clear-stream(_test-output-stream) -4112 # . . push args -4113 68/push _test-output-stream/imm32 -4114 # . . call -4115 e8/call clear-stream/disp32 -4116 # . . discard args -4117 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP -4118 # . clear-stream(_test-output-buffered-file+4) -4119 # . . push args -4120 b8/copy-to-EAX _test-output-buffered-file/imm32 -4121 05/add-to-EAX 4/imm32 -4122 50/push-EAX -4123 # . . call -4124 e8/call clear-stream/disp32 -4125 # . . discard args -4126 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP -4127 # initialize input -4128 # . write(_test-input-stream, "f2/m1 0f/m2 ab/m3 # comment") -4129 # . . push args -4130 68/push "f2/m1 0f/m2 ab/m3 # comment"/imm32 -4131 68/push _test-input-stream/imm32 -4132 # . . call -4133 e8/call write/disp32 -4134 # . . discard args -4135 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP -4136 # convert-instruction(_test-input-stream, _test-output-buffered-file) -4137 # . . push args -4138 68/push _test-output-buffered-file/imm32 -4139 68/push _test-input-stream/imm32 -4140 # . . call -4141 e8/call convert-instruction/disp32 -4142 # . . discard args -4143 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP -4144 # check output -4145 # . flush(_test-output-buffered-file) -4146 # . . push args -4147 68/push _test-output-buffered-file/imm32 -4148 # . . call -4149 e8/call flush/disp32 -4150 # . . discard args -4151 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP -4152 +-- 34 lines: #? # dump output --------------------------------------------------------------------------------------------------------------------------- -4186 # . check-stream-equal(_test-output-stream, "f2 0f ab # f2/m1 0f/m2 ab/m3 # comment", msg) -4187 # . . push args -4188 68/push "F - test-convert-instruction-handles-f2-0f-opcode"/imm32 -4189 68/push "f2 0f ab # f2/m1 0f/m2 ab/m3 # comment"/imm32 -4190 68/push _test-output-stream/imm32 -4191 # . . call -4192 e8/call check-stream-equal/disp32 -4193 # . . discard args -4194 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP -4195 # . epilog -4196 89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . . # copy EBP to ESP -4197 5d/pop-to-EBP -4198 c3/return -4199 -4200 test-convert-instruction-handles-f3-0f-opcode: -4201 # if the instruction starts with f3 0f opcode, include a second opcode -4202 # . prolog -4203 55/push-EBP -4204 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP -4205 # setup -4206 # . clear-stream(_test-input-stream) -4207 # . . push args -4208 68/push _test-input-stream/imm32 -4209 # . . call -4210 e8/call clear-stream/disp32 -4211 # . . discard args -4212 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP -4213 # . clear-stream(_test-output-stream) -4214 # . . push args -4215 68/push _test-output-stream/imm32 -4216 # . . call -4217 e8/call clear-stream/disp32 -4218 # . . discard args -4219 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP -4220 # . clear-stream(_test-output-buffered-file+4) +4086 68/push _test-output-buffered-file/imm32 +4087 68/push _test-input-stream/imm32 +4088 # . . call +4089 e8/call convert-instruction/disp32 +4090 # . . discard args +4091 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP +4092 # check output +4093 # . flush(_test-output-buffered-file) +4094 # . . push args +4095 68/push _test-output-buffered-file/imm32 +4096 # . . call +4097 e8/call flush/disp32 +4098 # . . discard args +4099 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP +4100 +-- 26 lines: #? # dump output --------------------------------------------------------------------------------------------------------------------------- +4126 # . check-stream-equal(_test-output-stream, "ab # f3/m1 0f/m2 ab/m3 # comment", msg) +4127 # . . push args +4128 68/push "F - test-convert-instruction-handles-unused-opcodes"/imm32 +4129 68/push "ab # ab/m1 cd/m2 # comment"/imm32 +4130 68/push _test-output-stream/imm32 +4131 # . . call +4132 e8/call check-stream-equal/disp32 +4133 # . . discard args +4134 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP +4135 # . epilog +4136 89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . . # copy EBP to ESP +4137 5d/pop-to-EBP +4138 c3/return +4139 +4140 test-convert-instruction-handles-unused-second-opcodes: +4141 # if the second opcode isn't 0f, don't include further opcodes +4142 # . prolog +4143 55/push-EBP +4144 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP +4145 # setup +4146 # . clear-stream(_test-input-stream) +4147 # . . push args +4148 68/push _test-input-stream/imm32 +4149 # . . call +4150 e8/call clear-stream/disp32 +4151 # . . discard args +4152 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP +4153 # . clear-stream(_test-output-stream) +4154 # . . push args +4155 68/push _test-output-stream/imm32 +4156 # . . call +4157 e8/call clear-stream/disp32 +4158 # . . discard args +4159 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP +4160 # . clear-stream(_test-output-buffered-file+4) +4161 # . . push args +4162 b8/copy-to-EAX _test-output-buffered-file/imm32 +4163 05/add-to-EAX 4/imm32 +4164 50/push-EAX +4165 # . . call +4166 e8/call clear-stream/disp32 +4167 # . . discard args +4168 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP +4169 # initialize input +4170 # . write(_test-input-stream, "f2/m1 ab/m2 cd/m3 # comment") +4171 # . . push args +4172 68/push "f2/m1 ab/m2 cd/m3 # comment"/imm32 +4173 68/push _test-input-stream/imm32 +4174 # . . call +4175 e8/call write/disp32 +4176 # . . discard args +4177 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP +4178 # convert-instruction(_test-input-stream, _test-output-buffered-file) +4179 # . . push args +4180 68/push _test-output-buffered-file/imm32 +4181 68/push _test-input-stream/imm32 +4182 # . . call +4183 e8/call convert-instruction/disp32 +4184 # . . discard args +4185 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP +4186 # check output +4187 # . flush(_test-output-buffered-file) +4188 # . . push args +4189 68/push _test-output-buffered-file/imm32 +4190 # . . call +4191 e8/call flush/disp32 +4192 # . . discard args +4193 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP +4194 +-- 26 lines: #? # dump output --------------------------------------------------------------------------------------------------------------------------- +4220 # . check-stream-equal(_test-output-stream, "f2 ab # f2/m1 ab/m2 cd/m3 # comment", msg) 4221 # . . push args -4222 b8/copy-to-EAX _test-output-buffered-file/imm32 -4223 05/add-to-EAX 4/imm32 -4224 50/push-EAX +4222 68/push "F - test-convert-instruction-handles-unused-second-opcodes"/imm32 +4223 68/push "f2 ab # f2/m1 ab/m2 cd/m3 # comment"/imm32 +4224 68/push _test-output-stream/imm32 4225 # . . call -4226 e8/call clear-stream/disp32 +4226 e8/call check-stream-equal/disp32 4227 # . . discard args -4228 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP -4229 # initialize input -4230 # . write(_test-input-stream, "f3/m1 0f/m2 ab/m3 # comment") -4231 # . . push args -4232 68/push "f3/m1 0f/m2 ab/m3 # comment"/imm32 -4233 68/push _test-input-stream/imm32 -4234 # . . call -4235 e8/call write/disp32 -4236 # . . discard args -4237 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP -4238 # convert-instruction(_test-input-stream, _test-output-buffered-file) -4239 # . . push args -4240 68/push _test-output-buffered-file/imm32 -4241 68/push _test-input-stream/imm32 -4242 # . . call -4243 e8/call convert-instruction/disp32 -4244 # . . discard args -4245 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP -4246 # check output -4247 # . flush(_test-output-buffered-file) +4228 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP +4229 # . epilog +4230 89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . . # copy EBP to ESP +4231 5d/pop-to-EBP +4232 c3/return +4233 +4234 test-convert-instruction-handles-unused-second-opcodes-2: +4235 # if the second opcode isn't 0f, don't include further opcodes +4236 # . prolog +4237 55/push-EBP +4238 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP +4239 # setup +4240 # . clear-stream(_test-input-stream) +4241 # . . push args +4242 68/push _test-input-stream/imm32 +4243 # . . call +4244 e8/call clear-stream/disp32 +4245 # . . discard args +4246 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP +4247 # . clear-stream(_test-output-stream) 4248 # . . push args -4249 68/push _test-output-buffered-file/imm32 +4249 68/push _test-output-stream/imm32 4250 # . . call -4251 e8/call flush/disp32 +4251 e8/call clear-stream/disp32 4252 # . . discard args 4253 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP -4254 +-- 34 lines: #? # dump output --------------------------------------------------------------------------------------------------------------------------- -4288 # . check-stream-equal(_test-output-stream, "f3 0f ab # f3/m1 0f/m2 ab/m3 # comment", msg) -4289 # . . push args -4290 68/push "F - test-convert-instruction-handles-f3-0f-opcode"/imm32 -4291 68/push "f3 0f ab # f3/m1 0f/m2 ab/m3 # comment"/imm32 -4292 68/push _test-output-stream/imm32 -4293 # . . call -4294 e8/call check-stream-equal/disp32 -4295 # . . discard args -4296 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP -4297 # . epilog -4298 89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . . # copy EBP to ESP -4299 5d/pop-to-EBP -4300 c3/return -4301 -4302 test-convert-instruction-handles-unused-opcodes: -4303 # if the instruction doesn't start with f2, f3 or 0f, don't include other opcodes -4304 # . prolog -4305 55/push-EBP -4306 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP -4307 # setup -4308 # . clear-stream(_test-input-stream) -4309 # . . push args -4310 68/push _test-input-stream/imm32 -4311 # . . call -4312 e8/call clear-stream/disp32 -4313 # . . discard args -4314 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP -4315 # . clear-stream(_test-output-stream) -4316 # . . push args -4317 68/push _test-output-stream/imm32 -4318 # . . call -4319 e8/call clear-stream/disp32 -4320 # . . discard args -4321 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP -4322 # . clear-stream(_test-output-buffered-file+4) -4323 # . . push args -4324 b8/copy-to-EAX _test-output-buffered-file/imm32 -4325 05/add-to-EAX 4/imm32 -4326 50/push-EAX -4327 # . . call -4328 e8/call clear-stream/disp32 -4329 # . . discard args -4330 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP -4331 # initialize input -4332 # . write(_test-input-stream, "ab/m1 cd/m2 # comment") -4333 # . . push args -4334 68/push "ab/m1 cd/m2 # comment"/imm32 -4335 68/push _test-input-stream/imm32 -4336 # . . call -4337 e8/call write/disp32 -4338 # . . discard args -4339 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP -4340 # convert-instruction(_test-input-stream, _test-output-buffered-file) -4341 # . . push args -4342 68/push _test-output-buffered-file/imm32 -4343 68/push _test-input-stream/imm32 +4254 # . clear-stream(_test-output-buffered-file+4) +4255 # . . push args +4256 b8/copy-to-EAX _test-output-buffered-file/imm32 +4257 05/add-to-EAX 4/imm32 +4258 50/push-EAX +4259 # . . call +4260 e8/call clear-stream/disp32 +4261 # . . discard args +4262 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP +4263 # initialize input +4264 # . write(_test-input-stream, "f3/m1 ab/m2 cd/m3 # comment") +4265 # . . push args +4266 68/push "f3/m1 ab/m2 cd/m3 # comment"/imm32 +4267 68/push _test-input-stream/imm32 +4268 # . . call +4269 e8/call write/disp32 +4270 # . . discard args +4271 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP +4272 # convert-instruction(_test-input-stream, _test-output-buffered-file) +4273 # . . push args +4274 68/push _test-output-buffered-file/imm32 +4275 68/push _test-input-stream/imm32 +4276 # . . call +4277 e8/call convert-instruction/disp32 +4278 # . . discard args +4279 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP +4280 # check output +4281 # . flush(_test-output-buffered-file) +4282 # . . push args +4283 68/push _test-output-buffered-file/imm32 +4284 # . . call +4285 e8/call flush/disp32 +4286 # . . discard args +4287 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP +4288 +-- 26 lines: #? # dump output --------------------------------------------------------------------------------------------------------------------------- +4314 # . check-stream-equal(_test-output-stream, "f3 ab # f3/m1 ab/m2 cd/m3 # comment", msg) +4315 # . . push args +4316 68/push "F - test-convert-instruction-handles-unused-second-opcodes"/imm32 +4317 68/push "f3 ab # f3/m1 ab/m2 cd/m3 # comment"/imm32 +4318 68/push _test-output-stream/imm32 +4319 # . . call +4320 e8/call check-stream-equal/disp32 +4321 # . . discard args +4322 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP +4323 # . epilog +4324 89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . . # copy EBP to ESP +4325 5d/pop-to-EBP +4326 c3/return +4327 +4328 test-convert-instruction-emits-modrm-byte: +4329 # pack mod, rm32 and r32 operands into ModR/M byte +4330 # . prolog +4331 55/push-EBP +4332 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP +4333 # setup +4334 # . clear-stream(_test-input-stream) +4335 # . . push args +4336 68/push _test-input-stream/imm32 +4337 # . . call +4338 e8/call clear-stream/disp32 +4339 # . . discard args +4340 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP +4341 # . clear-stream(_test-output-stream) +4342 # . . push args +4343 68/push _test-output-stream/imm32 4344 # . . call -4345 e8/call convert-instruction/disp32 +4345 e8/call clear-stream/disp32 4346 # . . discard args -4347 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP -4348 # check output -4349 # . flush(_test-output-buffered-file) -4350 # . . push args -4351 68/push _test-output-buffered-file/imm32 -4352 # . . call -4353 e8/call flush/disp32 -4354 # . . discard args -4355 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP -4356 +-- 34 lines: #? # dump output --------------------------------------------------------------------------------------------------------------------------- -4390 # . check-stream-equal(_test-output-stream, "ab # f3/m1 0f/m2 ab/m3 # comment", msg) -4391 # . . push args -4392 68/push "F - test-convert-instruction-handles-unused-opcodes"/imm32 -4393 68/push "ab # ab/m1 cd/m2 # comment"/imm32 -4394 68/push _test-output-stream/imm32 -4395 # . . call -4396 e8/call check-stream-equal/disp32 -4397 # . . discard args -4398 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP -4399 # . epilog -4400 89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . . # copy EBP to ESP -4401 5d/pop-to-EBP -4402 c3/return -4403 -4404 test-convert-instruction-handles-unused-second-opcodes: -4405 # if the second opcode isn't 0f, don't include further opcodes -4406 # . prolog -4407 55/push-EBP -4408 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP -4409 # setup -4410 # . clear-stream(_test-input-stream) -4411 # . . push args -4412 68/push _test-input-stream/imm32 +4347 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP +4348 # . clear-stream(_test-output-buffered-file+4) +4349 # . . push args +4350 b8/copy-to-EAX _test-output-buffered-file/imm32 +4351 05/add-to-EAX 4/imm32 +4352 50/push-EAX +4353 # . . call +4354 e8/call clear-stream/disp32 +4355 # . . discard args +4356 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP +4357 # initialize input +4358 # . write(_test-input-stream, "8b/copy 0/mod 0/rm32 1/r32") +4359 # . . push args +4360 68/push "8b/copy 0/mod 0/rm32 1/r32"/imm32 +4361 68/push _test-input-stream/imm32 +4362 # . . call +4363 e8/call write/disp32 +4364 # . . discard args +4365 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP +4366 # convert-instruction(_test-input-stream, _test-output-buffered-file) +4367 # . . push args +4368 68/push _test-output-buffered-file/imm32 +4369 68/push _test-input-stream/imm32 +4370 # . . call +4371 e8/call convert-instruction/disp32 +4372 # . . discard args +4373 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP +4374 # check output +4375 # . flush(_test-output-buffered-file) +4376 # . . push args +4377 68/push _test-output-buffered-file/imm32 +4378 # . . call +4379 e8/call flush/disp32 +4380 # . . discard args +4381 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP +4382 +-- 26 lines: #? # dump output --------------------------------------------------------------------------------------------------------------------------- +4408 # . check-stream-equal(_test-output-stream, "8b 08 # 8b/copy 0/mod 0/rm32 1/r32", msg) +4409 # . . push args +4410 68/push "F - test-convert-instruction-emits-modrm-byte"/imm32 +4411 68/push "8b 08 # 8b/copy 0/mod 0/rm32 1/r32"/imm32 +4412 68/push _test-output-stream/imm32 4413 # . . call -4414 e8/call clear-stream/disp32 +4414 e8/call check-stream-equal/disp32 4415 # . . discard args -4416 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP -4417 # . clear-stream(_test-output-stream) -4418 # . . push args -4419 68/push _test-output-stream/imm32 -4420 # . . call -4421 e8/call clear-stream/disp32 -4422 # . . discard args -4423 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP -4424 # . clear-stream(_test-output-buffered-file+4) -4425 # . . push args -4426 b8/copy-to-EAX _test-output-buffered-file/imm32 -4427 05/add-to-EAX 4/imm32 -4428 50/push-EAX -4429 # . . call -4430 e8/call clear-stream/disp32 -4431 # . . discard args -4432 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP -4433 # initialize input -4434 # . write(_test-input-stream, "f2/m1 ab/m2 cd/m3 # comment") -4435 # . . push args -4436 68/push "f2/m1 ab/m2 cd/m3 # comment"/imm32 -4437 68/push _test-input-stream/imm32 +4416 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP +4417 # . epilog +4418 89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . . # copy EBP to ESP +4419 5d/pop-to-EBP +4420 c3/return +4421 +4422 test-convert-instruction-emits-modrm-byte-from-subop: +4423 # pack mod, rm32 and subop operands into ModR/M byte +4424 # . prolog +4425 55/push-EBP +4426 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP +4427 # setup +4428 # . clear-stream(_test-input-stream) +4429 # . . push args +4430 68/push _test-input-stream/imm32 +4431 # . . call +4432 e8/call clear-stream/disp32 +4433 # . . discard args +4434 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP +4435 # . clear-stream(_test-output-stream) +4436 # . . push args +4437 68/push _test-output-stream/imm32 4438 # . . call -4439 e8/call write/disp32 +4439 e8/call clear-stream/disp32 4440 # . . discard args -4441 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP -4442 # convert-instruction(_test-input-stream, _test-output-buffered-file) +4441 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP +4442 # . clear-stream(_test-output-buffered-file+4) 4443 # . . push args -4444 68/push _test-output-buffered-file/imm32 -4445 68/push _test-input-stream/imm32 -4446 # . . call -4447 e8/call convert-instruction/disp32 -4448 # . . discard args -4449 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP -4450 # check output -4451 # . flush(_test-output-buffered-file) -4452 # . . push args -4453 68/push _test-output-buffered-file/imm32 -4454 # . . call -4455 e8/call flush/disp32 -4456 # . . discard args -4457 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP -4458 +-- 34 lines: #? # dump output --------------------------------------------------------------------------------------------------------------------------- -4492 # . check-stream-equal(_test-output-stream, "f2 ab # f2/m1 ab/m2 cd/m3 # comment", msg) -4493 # . . push args -4494 68/push "F - test-convert-instruction-handles-unused-second-opcodes"/imm32 -4495 68/push "f2 ab # f2/m1 ab/m2 cd/m3 # comment"/imm32 -4496 68/push _test-output-stream/imm32 -4497 # . . call -4498 e8/call check-stream-equal/disp32 -4499 # . . discard args -4500 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP -4501 # . epilog -4502 89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . . # copy EBP to ESP -4503 5d/pop-to-EBP -4504 c3/return -4505 -4506 test-convert-instruction-handles-unused-second-opcodes-2: -4507 # if the second opcode isn't 0f, don't include further opcodes -4508 # . prolog -4509 55/push-EBP -4510 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP -4511 # setup -4512 # . clear-stream(_test-input-stream) -4513 # . . push args -4514 68/push _test-input-stream/imm32 -4515 # . . call -4516 e8/call clear-stream/disp32 -4517 # . . discard args -4518 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP -4519 # . clear-stream(_test-output-stream) -4520 # . . push args -4521 68/push _test-output-stream/imm32 -4522 # . . call -4523 e8/call clear-stream/disp32 -4524 # . . discard args -4525 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP -4526 # . clear-stream(_test-output-buffered-file+4) -4527 # . . push args -4528 b8/copy-to-EAX _test-output-buffered-file/imm32 -4529 05/add-to-EAX 4/imm32 -4530 50/push-EAX -4531 # . . call -4532 e8/call clear-stream/disp32 -4533 # . . discard args -4534 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP -4535 # initialize input -4536 # . write(_test-input-stream, "f3/m1 ab/m2 cd/m3 # comment") +4444 b8/copy-to-EAX _test-output-buffered-file/imm32 +4445 05/add-to-EAX 4/imm32 +4446 50/push-EAX +4447 # . . call +4448 e8/call clear-stream/disp32 +4449 # . . discard args +4450 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP +4451 # initialize input +4452 # . write(_test-input-stream, "ff 6/subop/push 0/mod 0/rm32") +4453 # . . push args +4454 68/push "ff 6/subop/push 0/mod 0/rm32"/imm32 +4455 68/push _test-input-stream/imm32 +4456 # . . call +4457 e8/call write/disp32 +4458 # . . discard args +4459 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP +4460 # convert-instruction(_test-input-stream, _test-output-buffered-file) +4461 # . . push args +4462 68/push _test-output-buffered-file/imm32 +4463 68/push _test-input-stream/imm32 +4464 # . . call +4465 e8/call convert-instruction/disp32 +4466 # . . discard args +4467 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP +4468 # check output +4469 # . flush(_test-output-buffered-file) +4470 # . . push args +4471 68/push _test-output-buffered-file/imm32 +4472 # . . call +4473 e8/call flush/disp32 +4474 # . . discard args +4475 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP +4476 +-- 26 lines: #? # dump output --------------------------------------------------------------------------------------------------------------------------- +4502 # . check-stream-equal(_test-output-stream, "ff 30 # ff 6/subop/push 0/mod 0/rm32", msg) +4503 # . . push args +4504 68/push "F - test-convert-instruction-emits-modrm-byte-from-subop"/imm32 +4505 68/push "ff 30 # ff 6/subop/push 0/mod 0/rm32"/imm32 +4506 68/push _test-output-stream/imm32 +4507 # . . call +4508 e8/call check-stream-equal/disp32 +4509 # . . discard args +4510 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP +4511 # . epilog +4512 89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . . # copy EBP to ESP +4513 5d/pop-to-EBP +4514 c3/return +4515 +4516 test-convert-instruction-emits-modrm-byte-with-missing-mod: +4517 # pack rm32 and r32 operands into ModR/M byte +4518 # . prolog +4519 55/push-EBP +4520 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP +4521 # setup +4522 # . clear-stream(_test-input-stream) +4523 # . . push args +4524 68/push _test-input-stream/imm32 +4525 # . . call +4526 e8/call clear-stream/disp32 +4527 # . . discard args +4528 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP +4529 # . clear-stream(_test-output-stream) +4530 # . . push args +4531 68/push _test-output-stream/imm32 +4532 # . . call +4533 e8/call clear-stream/disp32 +4534 # . . discard args +4535 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP +4536 # . clear-stream(_test-output-buffered-file+4) 4537 # . . push args -4538 68/push "f3/m1 ab/m2 cd/m3 # comment"/imm32 -4539 68/push _test-input-stream/imm32 -4540 # . . call -4541 e8/call write/disp32 -4542 # . . discard args -4543 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP -4544 # convert-instruction(_test-input-stream, _test-output-buffered-file) -4545 # . . push args -4546 68/push _test-output-buffered-file/imm32 -4547 68/push _test-input-stream/imm32 -4548 # . . call -4549 e8/call convert-instruction/disp32 -4550 # . . discard args -4551 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP -4552 # check output -4553 # . flush(_test-output-buffered-file) -4554 # . . push args -4555 68/push _test-output-buffered-file/imm32 -4556 # . . call -4557 e8/call flush/disp32 -4558 # . . discard args -4559 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP -4560 +-- 34 lines: #? # dump output --------------------------------------------------------------------------------------------------------------------------- -4594 # . check-stream-equal(_test-output-stream, "f3 ab # f3/m1 ab/m2 cd/m3 # comment", msg) -4595 # . . push args -4596 68/push "F - test-convert-instruction-handles-unused-second-opcodes"/imm32 -4597 68/push "f3 ab # f3/m1 ab/m2 cd/m3 # comment"/imm32 -4598 68/push _test-output-stream/imm32 -4599 # . . call -4600 e8/call check-stream-equal/disp32 -4601 # . . discard args -4602 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP -4603 # . epilog -4604 89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . . # copy EBP to ESP -4605 5d/pop-to-EBP -4606 c3/return -4607 -4608 test-convert-instruction-emits-modrm-byte: -4609 # pack mod, rm32 and r32 operands into ModR/M byte -4610 # . prolog -4611 55/push-EBP -4612 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP -4613 # setup -4614 # . clear-stream(_test-input-stream) -4615 # . . push args -4616 68/push _test-input-stream/imm32 -4617 # . . call -4618 e8/call clear-stream/disp32 -4619 # . . discard args -4620 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP -4621 # . clear-stream(_test-output-stream) -4622 # . . push args -4623 68/push _test-output-stream/imm32 -4624 # . . call -4625 e8/call clear-stream/disp32 -4626 # . . discard args -4627 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP -4628 # . clear-stream(_test-output-buffered-file+4) -4629 # . . push args -4630 b8/copy-to-EAX _test-output-buffered-file/imm32 -4631 05/add-to-EAX 4/imm32 -4632 50/push-EAX -4633 # . . call -4634 e8/call clear-stream/disp32 -4635 # . . discard args -4636 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP -4637 # initialize input -4638 # . write(_test-input-stream, "8b/copy 0/mod 0/rm32 1/r32") -4639 # . . push args -4640 68/push "8b/copy 0/mod 0/rm32 1/r32"/imm32 -4641 68/push _test-input-stream/imm32 -4642 # . . call -4643 e8/call write/disp32 -4644 # . . discard args -4645 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP -4646 # convert-instruction(_test-input-stream, _test-output-buffered-file) -4647 # . . push args -4648 68/push _test-output-buffered-file/imm32 -4649 68/push _test-input-stream/imm32 -4650 # . . call -4651 e8/call convert-instruction/disp32 -4652 # . . discard args -4653 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP -4654 # check output -4655 # . flush(_test-output-buffered-file) -4656 # . . push args -4657 68/push _test-output-buffered-file/imm32 -4658 # . . call -4659 e8/call flush/disp32 -4660 # . . discard args -4661 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP -4662 +-- 34 lines: #? # dump output --------------------------------------------------------------------------------------------------------------------------- -4696 # . check-stream-equal(_test-output-stream, "8b 08 # 8b/copy 0/mod 0/rm32 1/r32", msg) -4697 # . . push args -4698 68/push "F - test-convert-instruction-emits-modrm-byte"/imm32 -4699 68/push "8b 08 # 8b/copy 0/mod 0/rm32 1/r32"/imm32 -4700 68/push _test-output-stream/imm32 -4701 # . . call -4702 e8/call check-stream-equal/disp32 -4703 # . . discard args -4704 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP -4705 # . epilog -4706 89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . . # copy EBP to ESP -4707 5d/pop-to-EBP -4708 c3/return -4709 -4710 test-convert-instruction-emits-modrm-byte-from-subop: -4711 # pack mod, rm32 and subop operands into ModR/M byte -4712 # . prolog -4713 55/push-EBP -4714 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP -4715 # setup -4716 # . clear-stream(_test-input-stream) -4717 # . . push args -4718 68/push _test-input-stream/imm32 -4719 # . . call -4720 e8/call clear-stream/disp32 -4721 # . . discard args -4722 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP -4723 # . clear-stream(_test-output-stream) -4724 # . . push args -4725 68/push _test-output-stream/imm32 -4726 # . . call -4727 e8/call clear-stream/disp32 -4728 # . . discard args -4729 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP -4730 # . clear-stream(_test-output-buffered-file+4) -4731 # . . push args -4732 b8/copy-to-EAX _test-output-buffered-file/imm32 -4733 05/add-to-EAX 4/imm32 -4734 50/push-EAX -4735 # . . call -4736 e8/call clear-stream/disp32 -4737 # . . discard args -4738 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP -4739 # initialize input -4740 # . write(_test-input-stream, "ff 6/subop/push 0/mod 0/rm32") -4741 # . . push args -4742 68/push "ff 6/subop/push 0/mod 0/rm32"/imm32 -4743 68/push _test-input-stream/imm32 -4744 # . . call -4745 e8/call write/disp32 -4746 # . . discard args -4747 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP -4748 # convert-instruction(_test-input-stream, _test-output-buffered-file) -4749 # . . push args -4750 68/push _test-output-buffered-file/imm32 -4751 68/push _test-input-stream/imm32 -4752 # . . call -4753 e8/call convert-instruction/disp32 -4754 # . . discard args -4755 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP -4756 # check output -4757 # . flush(_test-output-buffered-file) -4758 # . . push args -4759 68/push _test-output-buffered-file/imm32 -4760 # . . call -4761 e8/call flush/disp32 -4762 # . . discard args -4763 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP -4764 +-- 34 lines: #? # dump output --------------------------------------------------------------------------------------------------------------------------- -4798 # . check-stream-equal(_test-output-stream, "ff 30 # ff 6/subop/push 0/mod 0/rm32", msg) -4799 # . . push args -4800 68/push "F - test-convert-instruction-emits-modrm-byte-from-subop"/imm32 -4801 68/push "ff 30 # ff 6/subop/push 0/mod 0/rm32"/imm32 -4802 68/push _test-output-stream/imm32 -4803 # . . call -4804 e8/call check-stream-equal/disp32 -4805 # . . discard args -4806 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP -4807 # . epilog -4808 89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . . # copy EBP to ESP -4809 5d/pop-to-EBP -4810 c3/return -4811 -4812 test-convert-instruction-emits-modrm-byte-with-missing-mod: -4813 # pack rm32 and r32 operands into ModR/M byte -4814 # . prolog -4815 55/push-EBP -4816 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP -4817 # setup -4818 # . clear-stream(_test-input-stream) +4538 b8/copy-to-EAX _test-output-buffered-file/imm32 +4539 05/add-to-EAX 4/imm32 +4540 50/push-EAX +4541 # . . call +4542 e8/call clear-stream/disp32 +4543 # . . discard args +4544 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP +4545 # initialize input +4546 # . write(_test-input-stream, "8b/copy 0/rm32 1/r32") +4547 # . . push args +4548 68/push "8b/copy 0/rm32 1/r32"/imm32 +4549 68/push _test-input-stream/imm32 +4550 # . . call +4551 e8/call write/disp32 +4552 # . . discard args +4553 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP +4554 # convert-instruction(_test-input-stream, _test-output-buffered-file) +4555 # . . push args +4556 68/push _test-output-buffered-file/imm32 +4557 68/push _test-input-stream/imm32 +4558 # . . call +4559 e8/call convert-instruction/disp32 +4560 # . . discard args +4561 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP +4562 # check output +4563 # . flush(_test-output-buffered-file) +4564 # . . push args +4565 68/push _test-output-buffered-file/imm32 +4566 # . . call +4567 e8/call flush/disp32 +4568 # . . discard args +4569 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP +4570 +-- 26 lines: #? # dump output --------------------------------------------------------------------------------------------------------------------------- +4596 # . check-stream-equal(_test-output-stream, "8b 08 # 8b/copy 0/rm32 1/r32", msg) +4597 # . . push args +4598 68/push "F - test-convert-instruction-emits-modrm-byte-with-missing-mod"/imm32 +4599 68/push "8b 08 # 8b/copy 0/rm32 1/r32"/imm32 +4600 68/push _test-output-stream/imm32 +4601 # . . call +4602 e8/call check-stream-equal/disp32 +4603 # . . discard args +4604 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP +4605 # . epilog +4606 89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . . # copy EBP to ESP +4607 5d/pop-to-EBP +4608 c3/return +4609 +4610 test-convert-instruction-emits-modrm-byte-with-missing-rm32: +4611 # pack mod and r32 operands into ModR/M byte +4612 # . prolog +4613 55/push-EBP +4614 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP +4615 # setup +4616 # . clear-stream(_test-input-stream) +4617 # . . push args +4618 68/push _test-input-stream/imm32 +4619 # . . call +4620 e8/call clear-stream/disp32 +4621 # . . discard args +4622 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP +4623 # . clear-stream(_test-output-stream) +4624 # . . push args +4625 68/push _test-output-stream/imm32 +4626 # . . call +4627 e8/call clear-stream/disp32 +4628 # . . discard args +4629 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP +4630 # . clear-stream(_test-output-buffered-file+4) +4631 # . . push args +4632 b8/copy-to-EAX _test-output-buffered-file/imm32 +4633 05/add-to-EAX 4/imm32 +4634 50/push-EAX +4635 # . . call +4636 e8/call clear-stream/disp32 +4637 # . . discard args +4638 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP +4639 # initialize input +4640 # . write(_test-input-stream, "8b/copy 0/mod 1/r32") +4641 # . . push args +4642 68/push "8b/copy 0/mod 1/r32"/imm32 +4643 68/push _test-input-stream/imm32 +4644 # . . call +4645 e8/call write/disp32 +4646 # . . discard args +4647 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP +4648 # convert-instruction(_test-input-stream, _test-output-buffered-file) +4649 # . . push args +4650 68/push _test-output-buffered-file/imm32 +4651 68/push _test-input-stream/imm32 +4652 # . . call +4653 e8/call convert-instruction/disp32 +4654 # . . discard args +4655 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP +4656 # check output +4657 # . flush(_test-output-buffered-file) +4658 # . . push args +4659 68/push _test-output-buffered-file/imm32 +4660 # . . call +4661 e8/call flush/disp32 +4662 # . . discard args +4663 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP +4664 +-- 26 lines: #? # dump output --------------------------------------------------------------------------------------------------------------------------- +4690 # . check-stream-equal(_test-output-stream, "8b 08 # 8b/copy 0/mod 1/r32", msg) +4691 # . . push args +4692 68/push "F - test-convert-instruction-emits-modrm-byte-with-missing-rm32"/imm32 +4693 68/push "8b 08 # 8b/copy 0/mod 1/r32"/imm32 +4694 68/push _test-output-stream/imm32 +4695 # . . call +4696 e8/call check-stream-equal/disp32 +4697 # . . discard args +4698 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP +4699 # . epilog +4700 89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . . # copy EBP to ESP +4701 5d/pop-to-EBP +4702 c3/return +4703 +4704 test-convert-instruction-emits-modrm-byte-with-missing-r32: +4705 # pack mod and rm32 operands into ModR/M byte +4706 # . prolog +4707 55/push-EBP +4708 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP +4709 # setup +4710 # . clear-stream(_test-input-stream) +4711 # . . push args +4712 68/push _test-input-stream/imm32 +4713 # . . call +4714 e8/call clear-stream/disp32 +4715 # . . discard args +4716 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP +4717 # . clear-stream(_test-output-stream) +4718 # . . push args +4719 68/push _test-output-stream/imm32 +4720 # . . call +4721 e8/call clear-stream/disp32 +4722 # . . discard args +4723 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP +4724 # . clear-stream(_test-output-buffered-file+4) +4725 # . . push args +4726 b8/copy-to-EAX _test-output-buffered-file/imm32 +4727 05/add-to-EAX 4/imm32 +4728 50/push-EAX +4729 # . . call +4730 e8/call clear-stream/disp32 +4731 # . . discard args +4732 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP +4733 # initialize input +4734 # . write(_test-input-stream, "8b/copy 0/mod 0/rm32") +4735 # . . push args +4736 68/push "8b/copy 0/mod 0/rm32"/imm32 +4737 68/push _test-input-stream/imm32 +4738 # . . call +4739 e8/call write/disp32 +4740 # . . discard args +4741 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP +4742 # convert-instruction(_test-input-stream, _test-output-buffered-file) +4743 # . . push args +4744 68/push _test-output-buffered-file/imm32 +4745 68/push _test-input-stream/imm32 +4746 # . . call +4747 e8/call convert-instruction/disp32 +4748 # . . discard args +4749 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP +4750 # check output +4751 # . flush(_test-output-buffered-file) +4752 # . . push args +4753 68/push _test-output-buffered-file/imm32 +4754 # . . call +4755 e8/call flush/disp32 +4756 # . . discard args +4757 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP +4758 +-- 26 lines: #? # dump output --------------------------------------------------------------------------------------------------------------------------- +4784 # . check-stream-equal(_test-output-stream, "8b 00 # 8b/copy 0/mod 0/rm32", msg) +4785 # . . push args +4786 68/push "F - test-convert-instruction-emits-modrm-byte-with-missing-r32"/imm32 +4787 68/push "8b 00 # 8b/copy 0/mod 0/rm32"/imm32 +4788 68/push _test-output-stream/imm32 +4789 # . . call +4790 e8/call check-stream-equal/disp32 +4791 # . . discard args +4792 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP +4793 # . epilog +4794 89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . . # copy EBP to ESP +4795 5d/pop-to-EBP +4796 c3/return +4797 +4798 test-convert-instruction-emits-sib-byte: +4799 # pack base, index and scale operands into SIB byte +4800 # . prolog +4801 55/push-EBP +4802 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP +4803 # setup +4804 # . clear-stream(_test-input-stream) +4805 # . . push args +4806 68/push _test-input-stream/imm32 +4807 # . . call +4808 e8/call clear-stream/disp32 +4809 # . . discard args +4810 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP +4811 # . clear-stream(_test-output-stream) +4812 # . . push args +4813 68/push _test-output-stream/imm32 +4814 # . . call +4815 e8/call clear-stream/disp32 +4816 # . . discard args +4817 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP +4818 # . clear-stream(_test-output-buffered-file+4) 4819 # . . push args -4820 68/push _test-input-stream/imm32 -4821 # . . call -4822 e8/call clear-stream/disp32 -4823 # . . discard args -4824 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP -4825 # . clear-stream(_test-output-stream) -4826 # . . push args -4827 68/push _test-output-stream/imm32 -4828 # . . call -4829 e8/call clear-stream/disp32 -4830 # . . discard args -4831 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP -4832 # . clear-stream(_test-output-buffered-file+4) -4833 # . . push args -4834 b8/copy-to-EAX _test-output-buffered-file/imm32 -4835 05/add-to-EAX 4/imm32 -4836 50/push-EAX -4837 # . . call -4838 e8/call clear-stream/disp32 -4839 # . . discard args -4840 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP -4841 # initialize input -4842 # . write(_test-input-stream, "8b/copy 0/rm32 1/r32") -4843 # . . push args -4844 68/push "8b/copy 0/rm32 1/r32"/imm32 -4845 68/push _test-input-stream/imm32 -4846 # . . call -4847 e8/call write/disp32 -4848 # . . discard args -4849 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP -4850 # convert-instruction(_test-input-stream, _test-output-buffered-file) -4851 # . . push args -4852 68/push _test-output-buffered-file/imm32 -4853 68/push _test-input-stream/imm32 -4854 # . . call -4855 e8/call convert-instruction/disp32 -4856 # . . discard args -4857 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP -4858 # check output -4859 # . flush(_test-output-buffered-file) -4860 # . . push args -4861 68/push _test-output-buffered-file/imm32 -4862 # . . call -4863 e8/call flush/disp32 -4864 # . . discard args -4865 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP -4866 +-- 34 lines: #? # dump output --------------------------------------------------------------------------------------------------------------------------- -4900 # . check-stream-equal(_test-output-stream, "8b 08 # 8b/copy 0/rm32 1/r32", msg) -4901 # . . push args -4902 68/push "F - test-convert-instruction-emits-modrm-byte-with-missing-mod"/imm32 -4903 68/push "8b 08 # 8b/copy 0/rm32 1/r32"/imm32 -4904 68/push _test-output-stream/imm32 -4905 # . . call -4906 e8/call check-stream-equal/disp32 -4907 # . . discard args -4908 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP -4909 # . epilog -4910 89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . . # copy EBP to ESP -4911 5d/pop-to-EBP -4912 c3/return -4913 -4914 test-convert-instruction-emits-modrm-byte-with-missing-rm32: -4915 # pack mod and r32 operands into ModR/M byte -4916 # . prolog -4917 55/push-EBP -4918 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP -4919 # setup -4920 # . clear-stream(_test-input-stream) -4921 # . . push args -4922 68/push _test-input-stream/imm32 -4923 # . . call -4924 e8/call clear-stream/disp32 -4925 # . . discard args -4926 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP -4927 # . clear-stream(_test-output-stream) -4928 # . . push args -4929 68/push _test-output-stream/imm32 -4930 # . . call -4931 e8/call clear-stream/disp32 -4932 # . . discard args -4933 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP -4934 # . clear-stream(_test-output-buffered-file+4) -4935 # . . push args -4936 b8/copy-to-EAX _test-output-buffered-file/imm32 -4937 05/add-to-EAX 4/imm32 -4938 50/push-EAX -4939 # . . call -4940 e8/call clear-stream/disp32 -4941 # . . discard args -4942 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP -4943 # initialize input -4944 # . write(_test-input-stream, "8b/copy 0/mod 1/r32") -4945 # . . push args -4946 68/push "8b/copy 0/mod 1/r32"/imm32 -4947 68/push _test-input-stream/imm32 -4948 # . . call -4949 e8/call write/disp32 -4950 # . . discard args -4951 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP -4952 # convert-instruction(_test-input-stream, _test-output-buffered-file) -4953 # . . push args -4954 68/push _test-output-buffered-file/imm32 -4955 68/push _test-input-stream/imm32 -4956 # . . call -4957 e8/call convert-instruction/disp32 -4958 # . . discard args -4959 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP -4960 # check output -4961 # . flush(_test-output-buffered-file) -4962 # . . push args -4963 68/push _test-output-buffered-file/imm32 -4964 # . . call -4965 e8/call flush/disp32 -4966 # . . discard args -4967 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP -4968 +-- 34 lines: #? # dump output --------------------------------------------------------------------------------------------------------------------------- -5002 # . check-stream-equal(_test-output-stream, "8b 08 # 8b/copy 0/mod 1/r32", msg) -5003 # . . push args -5004 68/push "F - test-convert-instruction-emits-modrm-byte-with-missing-rm32"/imm32 -5005 68/push "8b 08 # 8b/copy 0/mod 1/r32"/imm32 -5006 68/push _test-output-stream/imm32 -5007 # . . call -5008 e8/call check-stream-equal/disp32 -5009 # . . discard args -5010 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP -5011 # . epilog -5012 89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . . # copy EBP to ESP -5013 5d/pop-to-EBP -5014 c3/return -5015 -5016 test-convert-instruction-emits-modrm-byte-with-missing-r32: -5017 # pack mod and rm32 operands into ModR/M byte -5018 # . prolog -5019 55/push-EBP -5020 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP -5021 # setup -5022 # . clear-stream(_test-input-stream) -5023 # . . push args -5024 68/push _test-input-stream/imm32 -5025 # . . call -5026 e8/call clear-stream/disp32 -5027 # . . discard args -5028 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP -5029 # . clear-stream(_test-output-stream) -5030 # . . push args -5031 68/push _test-output-stream/imm32 -5032 # . . call -5033 e8/call clear-stream/disp32 -5034 # . . discard args -5035 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP -5036 # . clear-stream(_test-output-buffered-file+4) -5037 # . . push args -5038 b8/copy-to-EAX _test-output-buffered-file/imm32 -5039 05/add-to-EAX 4/imm32 -5040 50/push-EAX -5041 # . . call -5042 e8/call clear-stream/disp32 -5043 # . . discard args -5044 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP -5045 # initialize input -5046 # . write(_test-input-stream, "8b/copy 0/mod 0/rm32") -5047 # . . push args -5048 68/push "8b/copy 0/mod 0/rm32"/imm32 -5049 68/push _test-input-stream/imm32 -5050 # . . call -5051 e8/call write/disp32 -5052 # . . discard args -5053 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP -5054 # convert-instruction(_test-input-stream, _test-output-buffered-file) -5055 # . . push args -5056 68/push _test-output-buffered-file/imm32 -5057 68/push _test-input-stream/imm32 -5058 # . . call -5059 e8/call convert-instruction/disp32 -5060 # . . discard args -5061 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP -5062 # check output -5063 # . flush(_test-output-buffered-file) -5064 # . . push args -5065 68/push _test-output-buffered-file/imm32 -5066 # . . call -5067 e8/call flush/disp32 -5068 # . . discard args -5069 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP -5070 +-- 34 lines: #? # dump output --------------------------------------------------------------------------------------------------------------------------- -5104 # . check-stream-equal(_test-output-stream, "8b 00 # 8b/copy 0/mod 0/rm32", msg) -5105 # . . push args -5106 68/push "F - test-convert-instruction-emits-modrm-byte-with-missing-r32"/imm32 -5107 68/push "8b 00 # 8b/copy 0/mod 0/rm32"/imm32 -5108 68/push _test-output-stream/imm32 -5109 # . . call -5110 e8/call check-stream-equal/disp32 -5111 # . . discard args -5112 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP -5113 # . epilog -5114 89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . . # copy EBP to ESP -5115 5d/pop-to-EBP -5116 c3/return -5117 -5118 test-convert-instruction-emits-sib-byte: -5119 # pack base, index and scale operands into SIB byte -5120 # . prolog -5121 55/push-EBP -5122 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP -5123 # setup -5124 # . clear-stream(_test-input-stream) -5125 # . . push args -5126 68/push _test-input-stream/imm32 -5127 # . . call -5128 e8/call clear-stream/disp32 -5129 # . . discard args -5130 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP -5131 # . clear-stream(_test-output-stream) -5132 # . . push args -5133 68/push _test-output-stream/imm32 -5134 # . . call -5135 e8/call clear-stream/disp32 -5136 # . . discard args -5137 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP -5138 # . clear-stream(_test-output-buffered-file+4) -5139 # . . push args -5140 b8/copy-to-EAX _test-output-buffered-file/imm32 -5141 05/add-to-EAX 4/imm32 -5142 50/push-EAX -5143 # . . call -5144 e8/call clear-stream/disp32 -5145 # . . discard args -5146 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP -5147 # initialize input -5148 # . write(_test-input-stream, "8b/copy 0/mod 4/rm32 1/r32 0/base 1/index 0/scale") -5149 # . . push args -5150 68/push "8b/copy 0/mod 4/rm32 1/r32 0/base 1/index 0/scale"/imm32 -5151 68/push _test-input-stream/imm32 -5152 # . . call -5153 e8/call write/disp32 -5154 # . . discard args -5155 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP -5156 # convert-instruction(_test-input-stream, _test-output-buffered-file) -5157 # . . push args -5158 68/push _test-output-buffered-file/imm32 -5159 68/push _test-input-stream/imm32 -5160 # . . call -5161 e8/call convert-instruction/disp32 -5162 # . . discard args -5163 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP -5164 # check output -5165 # . flush(_test-output-buffered-file) -5166 # . . push args -5167 68/push _test-output-buffered-file/imm32 -5168 # . . call -5169 e8/call flush/disp32 -5170 # . . discard args -5171 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP -5172 +-- 34 lines: #? # dump output --------------------------------------------------------------------------------------------------------------------------- -5206 # . check-stream-equal(_test-output-stream, "8b 08 # 8b/copy 0/mod 4/rm32 1/r32 0/base 1/index 0/scale", msg) -5207 # . . push args -5208 68/push "F - test-convert-instruction-emits-sib-byte"/imm32 -5209 68/push "8b 0c 08 # 8b/copy 0/mod 4/rm32 1/r32 0/base 1/index 0/scale"/imm32 -5210 68/push _test-output-stream/imm32 -5211 # . . call -5212 e8/call check-stream-equal/disp32 -5213 # . . discard args -5214 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP -5215 # . epilog -5216 89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . . # copy EBP to ESP -5217 5d/pop-to-EBP -5218 c3/return -5219 -5220 test-convert-instruction-emits-sib-byte-with-missing-base: -5221 # pack index and scale operands into SIB byte -5222 # . prolog -5223 55/push-EBP -5224 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP -5225 # setup -5226 # . clear-stream(_test-input-stream) -5227 # . . push args -5228 68/push _test-input-stream/imm32 -5229 # . . call -5230 e8/call clear-stream/disp32 -5231 # . . discard args -5232 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP -5233 # . clear-stream(_test-output-stream) -5234 # . . push args -5235 68/push _test-output-stream/imm32 -5236 # . . call -5237 e8/call clear-stream/disp32 -5238 # . . discard args -5239 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP -5240 # . clear-stream(_test-output-buffered-file+4) -5241 # . . push args -5242 b8/copy-to-EAX _test-output-buffered-file/imm32 -5243 05/add-to-EAX 4/imm32 -5244 50/push-EAX -5245 # . . call -5246 e8/call clear-stream/disp32 -5247 # . . discard args -5248 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP -5249 # initialize input -5250 # . write(_test-input-stream, "8b/copy 0/mod 4/rm32 1/r32 1/index 0/scale") -5251 # . . push args -5252 68/push "8b/copy 0/mod 4/rm32 1/r32 1/index 0/scale"/imm32 -5253 68/push _test-input-stream/imm32 -5254 # . . call -5255 e8/call write/disp32 -5256 # . . discard args -5257 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP -5258 # convert-instruction(_test-input-stream, _test-output-buffered-file) -5259 # . . push args -5260 68/push _test-output-buffered-file/imm32 -5261 68/push _test-input-stream/imm32 -5262 # . . call -5263 e8/call convert-instruction/disp32 -5264 # . . discard args -5265 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP -5266 # check output -5267 # . flush(_test-output-buffered-file) -5268 # . . push args -5269 68/push _test-output-buffered-file/imm32 -5270 # . . call -5271 e8/call flush/disp32 -5272 # . . discard args -5273 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP -5274 +-- 34 lines: #? # dump output --------------------------------------------------------------------------------------------------------------------------- -5308 # . check-stream-equal(_test-output-stream, "8b 0c 08 # 8b/copy 0/mod 4/rm32 1/r32 1/index 0/scale", msg) -5309 # . . push args -5310 68/push "F - test-convert-instruction-emits-sib-byte-with-missing-base"/imm32 -5311 68/push "8b 0c 08 # 8b/copy 0/mod 4/rm32 1/r32 1/index 0/scale"/imm32 -5312 68/push _test-output-stream/imm32 -5313 # . . call -5314 e8/call check-stream-equal/disp32 -5315 # . . discard args -5316 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP -5317 # . epilog -5318 89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . . # copy EBP to ESP -5319 5d/pop-to-EBP -5320 c3/return -5321 -5322 test-convert-instruction-emits-sib-byte-with-missing-index: -5323 # pack base and scale operands into SIB byte -5324 # . prolog -5325 55/push-EBP -5326 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP -5327 # setup -5328 # . clear-stream(_test-input-stream) -5329 # . . push args -5330 68/push _test-input-stream/imm32 -5331 # . . call -5332 e8/call clear-stream/disp32 -5333 # . . discard args -5334 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP -5335 # . clear-stream(_test-output-stream) -5336 # . . push args -5337 68/push _test-output-stream/imm32 -5338 # . . call -5339 e8/call clear-stream/disp32 -5340 # . . discard args -5341 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP -5342 # . clear-stream(_test-output-buffered-file+4) -5343 # . . push args -5344 b8/copy-to-EAX _test-output-buffered-file/imm32 -5345 05/add-to-EAX 4/imm32 -5346 50/push-EAX -5347 # . . call -5348 e8/call clear-stream/disp32 -5349 # . . discard args -5350 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP -5351 # initialize input -5352 # . write(_test-input-stream, "8b/copy 0/mod 4/rm32 1/r32 0/base 0/scale") -5353 # . . push args -5354 68/push "8b/copy 0/mod 4/rm32 1/r32 0/base 0/scale"/imm32 -5355 68/push _test-input-stream/imm32 -5356 # . . call -5357 e8/call write/disp32 -5358 # . . discard args -5359 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP -5360 # convert-instruction(_test-input-stream, _test-output-buffered-file) -5361 # . . push args -5362 68/push _test-output-buffered-file/imm32 -5363 68/push _test-input-stream/imm32 -5364 # . . call -5365 e8/call convert-instruction/disp32 -5366 # . . discard args -5367 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP -5368 # check output -5369 # . flush(_test-output-buffered-file) -5370 # . . push args -5371 68/push _test-output-buffered-file/imm32 -5372 # . . call -5373 e8/call flush/disp32 -5374 # . . discard args -5375 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP -5376 +-- 34 lines: #? # dump output --------------------------------------------------------------------------------------------------------------------------- -5410 # . check-stream-equal(_test-output-stream, "8b 0c 08 # 8b/copy 0/mod 4/rm32 1/r32 0/base 0/scale", msg) -5411 # . . push args -5412 68/push "F - test-convert-instruction-emits-sib-byte-with-missing-index"/imm32 -5413 68/push "8b 0c 00 # 8b/copy 0/mod 4/rm32 1/r32 0/base 0/scale"/imm32 -5414 68/push _test-output-stream/imm32 -5415 # . . call -5416 e8/call check-stream-equal/disp32 -5417 # . . discard args -5418 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP -5419 # . epilog -5420 89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . . # copy EBP to ESP -5421 5d/pop-to-EBP -5422 c3/return -5423 -5424 test-convert-instruction-emits-sib-byte-with-missing-scale: -5425 # pack base and index operands into SIB byte -5426 # . prolog -5427 55/push-EBP -5428 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP -5429 # setup -5430 # . clear-stream(_test-input-stream) -5431 # . . push args -5432 68/push _test-input-stream/imm32 -5433 # . . call -5434 e8/call clear-stream/disp32 -5435 # . . discard args -5436 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP -5437 # . clear-stream(_test-output-stream) -5438 # . . push args -5439 68/push _test-output-stream/imm32 -5440 # . . call -5441 e8/call clear-stream/disp32 -5442 # . . discard args -5443 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP -5444 # . clear-stream(_test-output-buffered-file+4) -5445 # . . push args -5446 b8/copy-to-EAX _test-output-buffered-file/imm32 -5447 05/add-to-EAX 4/imm32 -5448 50/push-EAX -5449 # . . call -5450 e8/call clear-stream/disp32 -5451 # . . discard args -5452 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP -5453 # initialize input -5454 # . write(_test-input-stream, "8b/copy 0/mod 4/rm32 1/r32 0/base 1/index") -5455 # . . push args -5456 68/push "8b/copy 0/mod 4/rm32 1/r32 0/base 1/index"/imm32 -5457 68/push _test-input-stream/imm32 -5458 # . . call -5459 e8/call write/disp32 -5460 # . . discard args -5461 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP -5462 # convert-instruction(_test-input-stream, _test-output-buffered-file) +4820 b8/copy-to-EAX _test-output-buffered-file/imm32 +4821 05/add-to-EAX 4/imm32 +4822 50/push-EAX +4823 # . . call +4824 e8/call clear-stream/disp32 +4825 # . . discard args +4826 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP +4827 # initialize input +4828 # . write(_test-input-stream, "8b/copy 0/mod 4/rm32 1/r32 0/base 1/index 0/scale") +4829 # . . push args +4830 68/push "8b/copy 0/mod 4/rm32 1/r32 0/base 1/index 0/scale"/imm32 +4831 68/push _test-input-stream/imm32 +4832 # . . call +4833 e8/call write/disp32 +4834 # . . discard args +4835 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP +4836 # convert-instruction(_test-input-stream, _test-output-buffered-file) +4837 # . . push args +4838 68/push _test-output-buffered-file/imm32 +4839 68/push _test-input-stream/imm32 +4840 # . . call +4841 e8/call convert-instruction/disp32 +4842 # . . discard args +4843 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP +4844 # check output +4845 # . flush(_test-output-buffered-file) +4846 # . . push args +4847 68/push _test-output-buffered-file/imm32 +4848 # . . call +4849 e8/call flush/disp32 +4850 # . . discard args +4851 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP +4852 +-- 26 lines: #? # dump output --------------------------------------------------------------------------------------------------------------------------- +4878 # . check-stream-equal(_test-output-stream, "8b 08 # 8b/copy 0/mod 4/rm32 1/r32 0/base 1/index 0/scale", msg) +4879 # . . push args +4880 68/push "F - test-convert-instruction-emits-sib-byte"/imm32 +4881 68/push "8b 0c 08 # 8b/copy 0/mod 4/rm32 1/r32 0/base 1/index 0/scale"/imm32 +4882 68/push _test-output-stream/imm32 +4883 # . . call +4884 e8/call check-stream-equal/disp32 +4885 # . . discard args +4886 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP +4887 # . epilog +4888 89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . . # copy EBP to ESP +4889 5d/pop-to-EBP +4890 c3/return +4891 +4892 test-convert-instruction-emits-sib-byte-with-missing-base: +4893 # pack index and scale operands into SIB byte +4894 # . prolog +4895 55/push-EBP +4896 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP +4897 # setup +4898 # . clear-stream(_test-input-stream) +4899 # . . push args +4900 68/push _test-input-stream/imm32 +4901 # . . call +4902 e8/call clear-stream/disp32 +4903 # . . discard args +4904 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP +4905 # . clear-stream(_test-output-stream) +4906 # . . push args +4907 68/push _test-output-stream/imm32 +4908 # . . call +4909 e8/call clear-stream/disp32 +4910 # . . discard args +4911 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP +4912 # . clear-stream(_test-output-buffered-file+4) +4913 # . . push args +4914 b8/copy-to-EAX _test-output-buffered-file/imm32 +4915 05/add-to-EAX 4/imm32 +4916 50/push-EAX +4917 # . . call +4918 e8/call clear-stream/disp32 +4919 # . . discard args +4920 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP +4921 # initialize input +4922 # . write(_test-input-stream, "8b/copy 0/mod 4/rm32 1/r32 1/index 0/scale") +4923 # . . push args +4924 68/push "8b/copy 0/mod 4/rm32 1/r32 1/index 0/scale"/imm32 +4925 68/push _test-input-stream/imm32 +4926 # . . call +4927 e8/call write/disp32 +4928 # . . discard args +4929 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP +4930 # convert-instruction(_test-input-stream, _test-output-buffered-file) +4931 # . . push args +4932 68/push _test-output-buffered-file/imm32 +4933 68/push _test-input-stream/imm32 +4934 # . . call +4935 e8/call convert-instruction/disp32 +4936 # . . discard args +4937 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP +4938 # check output +4939 # . flush(_test-output-buffered-file) +4940 # . . push args +4941 68/push _test-output-buffered-file/imm32 +4942 # . . call +4943 e8/call flush/disp32 +4944 # . . discard args +4945 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP +4946 +-- 26 lines: #? # dump output --------------------------------------------------------------------------------------------------------------------------- +4972 # . check-stream-equal(_test-output-stream, "8b 0c 08 # 8b/copy 0/mod 4/rm32 1/r32 1/index 0/scale", msg) +4973 # . . push args +4974 68/push "F - test-convert-instruction-emits-sib-byte-with-missing-base"/imm32 +4975 68/push "8b 0c 08 # 8b/copy 0/mod 4/rm32 1/r32 1/index 0/scale"/imm32 +4976 68/push _test-output-stream/imm32 +4977 # . . call +4978 e8/call check-stream-equal/disp32 +4979 # . . discard args +4980 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP +4981 # . epilog +4982 89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . . # copy EBP to ESP +4983 5d/pop-to-EBP +4984 c3/return +4985 +4986 test-convert-instruction-emits-sib-byte-with-missing-index: +4987 # pack base and scale operands into SIB byte +4988 # . prolog +4989 55/push-EBP +4990 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP +4991 # setup +4992 # . clear-stream(_test-input-stream) +4993 # . . push args +4994 68/push _test-input-stream/imm32 +4995 # . . call +4996 e8/call clear-stream/disp32 +4997 # . . discard args +4998 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP +4999 # . clear-stream(_test-output-stream) +5000 # . . push args +5001 68/push _test-output-stream/imm32 +5002 # . . call +5003 e8/call clear-stream/disp32 +5004 # . . discard args +5005 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP +5006 # . clear-stream(_test-output-buffered-file+4) +5007 # . . push args +5008 b8/copy-to-EAX _test-output-buffered-file/imm32 +5009 05/add-to-EAX 4/imm32 +5010 50/push-EAX +5011 # . . call +5012 e8/call clear-stream/disp32 +5013 # . . discard args +5014 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP +5015 # initialize input +5016 # . write(_test-input-stream, "8b/copy 0/mod 4/rm32 1/r32 0/base 0/scale") +5017 # . . push args +5018 68/push "8b/copy 0/mod 4/rm32 1/r32 0/base 0/scale"/imm32 +5019 68/push _test-input-stream/imm32 +5020 # . . call +5021 e8/call write/disp32 +5022 # . . discard args +5023 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP +5024 # convert-instruction(_test-input-stream, _test-output-buffered-file) +5025 # . . push args +5026 68/push _test-output-buffered-file/imm32 +5027 68/push _test-input-stream/imm32 +5028 # . . call +5029 e8/call convert-instruction/disp32 +5030 # . . discard args +5031 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP +5032 # check output +5033 # . flush(_test-output-buffered-file) +5034 # . . push args +5035 68/push _test-output-buffered-file/imm32 +5036 # . . call +5037 e8/call flush/disp32 +5038 # . . discard args +5039 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP +5040 +-- 26 lines: #? # dump output --------------------------------------------------------------------------------------------------------------------------- +5066 # . check-stream-equal(_test-output-stream, "8b 0c 08 # 8b/copy 0/mod 4/rm32 1/r32 0/base 0/scale", msg) +5067 # . . push args +5068 68/push "F - test-convert-instruction-emits-sib-byte-with-missing-index"/imm32 +5069 68/push "8b 0c 00 # 8b/copy 0/mod 4/rm32 1/r32 0/base 0/scale"/imm32 +5070 68/push _test-output-stream/imm32 +5071 # . . call +5072 e8/call check-stream-equal/disp32 +5073 # . . discard args +5074 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP +5075 # . epilog +5076 89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . . # copy EBP to ESP +5077 5d/pop-to-EBP +5078 c3/return +5079 +5080 test-convert-instruction-emits-sib-byte-with-missing-scale: +5081 # pack base and index operands into SIB byte +5082 # . prolog +5083 55/push-EBP +5084 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP +5085 # setup +5086 # . clear-stream(_test-input-stream) +5087 # . . push args +5088 68/push _test-input-stream/imm32 +5089 # . . call +5090 e8/call clear-stream/disp32 +5091 # . . discard args +5092 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP +5093 # . clear-stream(_test-output-stream) +5094 # . . push args +5095 68/push _test-output-stream/imm32 +5096 # . . call +5097 e8/call clear-stream/disp32 +5098 # . . discard args +5099 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP +5100 # . clear-stream(_test-output-buffered-file+4) +5101 # . . push args +5102 b8/copy-to-EAX _test-output-buffered-file/imm32 +5103 05/add-to-EAX 4/imm32 +5104 50/push-EAX +5105 # . . call +5106 e8/call clear-stream/disp32 +5107 # . . discard args +5108 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP +5109 # initialize input +5110 # . write(_test-input-stream, "8b/copy 0/mod 4/rm32 1/r32 0/base 1/index") +5111 # . . push args +5112 68/push "8b/copy 0/mod 4/rm32 1/r32 0/base 1/index"/imm32 +5113 68/push _test-input-stream/imm32 +5114 # . . call +5115 e8/call write/disp32 +5116 # . . discard args +5117 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP +5118 # convert-instruction(_test-input-stream, _test-output-buffered-file) +5119 # . . push args +5120 68/push _test-output-buffered-file/imm32 +5121 68/push _test-input-stream/imm32 +5122 # . . call +5123 e8/call convert-instruction/disp32 +5124 # . . discard args +5125 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP +5126 # check output +5127 # . flush(_test-output-buffered-file) +5128 # . . push args +5129 68/push _test-output-buffered-file/imm32 +5130 # . . call +5131 e8/call flush/disp32 +5132 # . . discard args +5133 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP +5134 +-- 26 lines: #? # dump output --------------------------------------------------------------------------------------------------------------------------- +5160 # . check-stream-equal(_test-output-stream, "8b 0c 08 # 8b/copy 0/mod 4/rm32 1/r32 0/base 1/index", msg) +5161 # . . push args +5162 68/push "F - test-convert-instruction-emits-sib-byte-with-missing-scale"/imm32 +5163 68/push "8b 0c 08 # 8b/copy 0/mod 4/rm32 1/r32 0/base 1/index"/imm32 +5164 68/push _test-output-stream/imm32 +5165 # . . call +5166 e8/call check-stream-equal/disp32 +5167 # . . discard args +5168 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP +5169 # . epilog +5170 89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . . # copy EBP to ESP +5171 5d/pop-to-EBP +5172 c3/return +5173 +5174 test-convert-instruction-handles-disp32-operand: +5175 # expand /disp32 operand into 4 bytes +5176 # . prolog +5177 55/push-EBP +5178 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP +5179 # setup +5180 # . clear-stream(_test-input-stream) +5181 # . . push args +5182 68/push _test-input-stream/imm32 +5183 # . . call +5184 e8/call clear-stream/disp32 +5185 # . . discard args +5186 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP +5187 # . clear-stream(_test-output-stream) +5188 # . . push args +5189 68/push _test-output-stream/imm32 +5190 # . . call +5191 e8/call clear-stream/disp32 +5192 # . . discard args +5193 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP +5194 # . clear-stream(_test-output-buffered-file+4) +5195 # . . push args +5196 b8/copy-to-EAX _test-output-buffered-file/imm32 +5197 05/add-to-EAX 4/imm32 +5198 50/push-EAX +5199 # . . call +5200 e8/call clear-stream/disp32 +5201 # . . discard args +5202 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP +5203 # initialize input +5204 # . write(_test-input-stream, "e8/call 20/disp32") +5205 # . . push args +5206 68/push "e8/call 20/disp32"/imm32 +5207 68/push _test-input-stream/imm32 +5208 # . . call +5209 e8/call write/disp32 +5210 # . . discard args +5211 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP +5212 # convert-instruction(_test-input-stream, _test-output-buffered-file) +5213 # . . push args +5214 68/push _test-output-buffered-file/imm32 +5215 68/push _test-input-stream/imm32 +5216 # . . call +5217 e8/call convert-instruction/disp32 +5218 # . . discard args +5219 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP +5220 # check output +5221 # . flush(_test-output-buffered-file) +5222 # . . push args +5223 68/push _test-output-buffered-file/imm32 +5224 # . . call +5225 e8/call flush/disp32 +5226 # . . discard args +5227 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP +5228 +-- 26 lines: #? # dump output --------------------------------------------------------------------------------------------------------------------------- +5254 # . check-stream-equal(_test-output-stream, "e8 20 00 00 00 # e8/call 20/disp32", msg) +5255 # . . push args +5256 68/push "F - test-convert-instruction-handles-disp32-operand"/imm32 +5257 68/push "e8 20 00 00 00 # e8/call 20/disp32"/imm32 +5258 68/push _test-output-stream/imm32 +5259 # . . call +5260 e8/call check-stream-equal/disp32 +5261 # . . discard args +5262 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP +5263 # . epilog +5264 89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . . # copy EBP to ESP +5265 5d/pop-to-EBP +5266 c3/return +5267 +5268 test-convert-instruction-handles-disp16-operand: +5269 # expand /disp16 operand into 2 bytes +5270 # . prolog +5271 55/push-EBP +5272 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP +5273 # setup +5274 # . clear-stream(_test-input-stream) +5275 # . . push args +5276 68/push _test-input-stream/imm32 +5277 # . . call +5278 e8/call clear-stream/disp32 +5279 # . . discard args +5280 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP +5281 # . clear-stream(_test-output-stream) +5282 # . . push args +5283 68/push _test-output-stream/imm32 +5284 # . . call +5285 e8/call clear-stream/disp32 +5286 # . . discard args +5287 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP +5288 # . clear-stream(_test-output-buffered-file+4) +5289 # . . push args +5290 b8/copy-to-EAX _test-output-buffered-file/imm32 +5291 05/add-to-EAX 4/imm32 +5292 50/push-EAX +5293 # . . call +5294 e8/call clear-stream/disp32 +5295 # . . discard args +5296 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP +5297 # initialize input +5298 # . write(_test-input-stream, "e8/call 20/disp16") +5299 # . . push args +5300 68/push "e8/call 20/disp16"/imm32 # not a valid instruction +5301 68/push _test-input-stream/imm32 +5302 # . . call +5303 e8/call write/disp32 +5304 # . . discard args +5305 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP +5306 # convert-instruction(_test-input-stream, _test-output-buffered-file) +5307 # . . push args +5308 68/push _test-output-buffered-file/imm32 +5309 68/push _test-input-stream/imm32 +5310 # . . call +5311 e8/call convert-instruction/disp32 +5312 # . . discard args +5313 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP +5314 # check output +5315 # . flush(_test-output-buffered-file) +5316 # . . push args +5317 68/push _test-output-buffered-file/imm32 +5318 # . . call +5319 e8/call flush/disp32 +5320 # . . discard args +5321 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP +5322 +-- 26 lines: #? # dump output --------------------------------------------------------------------------------------------------------------------------- +5348 # . check-stream-equal(_test-output-stream, "e8 20 00 # e8/call 20/disp16", msg) +5349 # . . push args +5350 68/push "F - test-convert-instruction-handles-disp16-operand"/imm32 +5351 68/push "e8 20 00 # e8/call 20/disp16"/imm32 +5352 68/push _test-output-stream/imm32 +5353 # . . call +5354 e8/call check-stream-equal/disp32 +5355 # . . discard args +5356 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP +5357 # . epilog +5358 89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . . # copy EBP to ESP +5359 5d/pop-to-EBP +5360 c3/return +5361 +5362 test-convert-instruction-handles-disp8-operand: +5363 # expand /disp8 operand into 1 byte +5364 # . prolog +5365 55/push-EBP +5366 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP +5367 # setup +5368 # . clear-stream(_test-input-stream) +5369 # . . push args +5370 68/push _test-input-stream/imm32 +5371 # . . call +5372 e8/call clear-stream/disp32 +5373 # . . discard args +5374 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP +5375 # . clear-stream(_test-output-stream) +5376 # . . push args +5377 68/push _test-output-stream/imm32 +5378 # . . call +5379 e8/call clear-stream/disp32 +5380 # . . discard args +5381 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP +5382 # . clear-stream(_test-output-buffered-file+4) +5383 # . . push args +5384 b8/copy-to-EAX _test-output-buffered-file/imm32 +5385 05/add-to-EAX 4/imm32 +5386 50/push-EAX +5387 # . . call +5388 e8/call clear-stream/disp32 +5389 # . . discard args +5390 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP +5391 # initialize input +5392 # . write(_test-input-stream, "eb/jump 20/disp8") +5393 # . . push args +5394 68/push "eb/jump 20/disp8"/imm32 +5395 68/push _test-input-stream/imm32 +5396 # . . call +5397 e8/call write/disp32 +5398 # . . discard args +5399 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP +5400 # convert-instruction(_test-input-stream, _test-output-buffered-file) +5401 # . . push args +5402 68/push _test-output-buffered-file/imm32 +5403 68/push _test-input-stream/imm32 +5404 # . . call +5405 e8/call convert-instruction/disp32 +5406 # . . discard args +5407 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP +5408 # check output +5409 # . flush(_test-output-buffered-file) +5410 # . . push args +5411 68/push _test-output-buffered-file/imm32 +5412 # . . call +5413 e8/call flush/disp32 +5414 # . . discard args +5415 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP +5416 +-- 26 lines: #? # dump output --------------------------------------------------------------------------------------------------------------------------- +5442 # . check-stream-equal(_test-output-stream, "eb 20 # eb/jump 20/disp8", msg) +5443 # . . push args +5444 68/push "F - test-convert-instruction-handles-disp8-operand"/imm32 +5445 68/push "eb 20 # eb/jump 20/disp8"/imm32 +5446 68/push _test-output-stream/imm32 +5447 # . . call +5448 e8/call check-stream-equal/disp32 +5449 # . . discard args +5450 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP +5451 # . epilog +5452 89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . . # copy EBP to ESP +5453 5d/pop-to-EBP +5454 c3/return +5455 +5456 test-convert-instruction-handles-disp8-name: +5457 # pass /disp8 name directly through +5458 # . prolog +5459 55/push-EBP +5460 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP +5461 # setup +5462 # . clear-stream(_test-input-stream) 5463 # . . push args -5464 68/push _test-output-buffered-file/imm32 -5465 68/push _test-input-stream/imm32 -5466 # . . call -5467 e8/call convert-instruction/disp32 -5468 # . . discard args -5469 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP -5470 # check output -5471 # . flush(_test-output-buffered-file) -5472 # . . push args -5473 68/push _test-output-buffered-file/imm32 -5474 # . . call -5475 e8/call flush/disp32 -5476 # . . discard args -5477 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP -5478 +-- 34 lines: #? # dump output --------------------------------------------------------------------------------------------------------------------------- -5512 # . check-stream-equal(_test-output-stream, "8b 0c 08 # 8b/copy 0/mod 4/rm32 1/r32 0/base 1/index", msg) -5513 # . . push args -5514 68/push "F - test-convert-instruction-emits-sib-byte-with-missing-scale"/imm32 -5515 68/push "8b 0c 08 # 8b/copy 0/mod 4/rm32 1/r32 0/base 1/index"/imm32 -5516 68/push _test-output-stream/imm32 -5517 # . . call -5518 e8/call check-stream-equal/disp32 -5519 # . . discard args -5520 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP -5521 # . epilog -5522 89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . . # copy EBP to ESP -5523 5d/pop-to-EBP -5524 c3/return -5525 -5526 test-convert-instruction-handles-disp32-operand: -5527 # expand /disp32 operand into 4 bytes -5528 # . prolog -5529 55/push-EBP -5530 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP -5531 # setup -5532 # . clear-stream(_test-input-stream) -5533 # . . push args -5534 68/push _test-input-stream/imm32 -5535 # . . call -5536 e8/call clear-stream/disp32 -5537 # . . discard args -5538 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP -5539 # . clear-stream(_test-output-stream) -5540 # . . push args -5541 68/push _test-output-stream/imm32 -5542 # . . call -5543 e8/call clear-stream/disp32 -5544 # . . discard args -5545 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP -5546 # . clear-stream(_test-output-buffered-file+4) -5547 # . . push args -5548 b8/copy-to-EAX _test-output-buffered-file/imm32 -5549 05/add-to-EAX 4/imm32 -5550 50/push-EAX -5551 # . . call -5552 e8/call clear-stream/disp32 -5553 # . . discard args -5554 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP -5555 # initialize input -5556 # . write(_test-input-stream, "e8/call 20/disp32") +5464 68/push _test-input-stream/imm32 +5465 # . . call +5466 e8/call clear-stream/disp32 +5467 # . . discard args +5468 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP +5469 # . clear-stream(_test-output-stream) +5470 # . . push args +5471 68/push _test-output-stream/imm32 +5472 # . . call +5473 e8/call clear-stream/disp32 +5474 # . . discard args +5475 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP +5476 # . clear-stream(_test-output-buffered-file+4) +5477 # . . push args +5478 b8/copy-to-EAX _test-output-buffered-file/imm32 +5479 05/add-to-EAX 4/imm32 +5480 50/push-EAX +5481 # . . call +5482 e8/call clear-stream/disp32 +5483 # . . discard args +5484 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP +5485 # initialize input +5486 # . write(_test-input-stream, "eb/jump xyz/disp8") +5487 # . . push args +5488 68/push "eb/jump xyz/disp8"/imm32 +5489 68/push _test-input-stream/imm32 +5490 # . . call +5491 e8/call write/disp32 +5492 # . . discard args +5493 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP +5494 # convert-instruction(_test-input-stream, _test-output-buffered-file) +5495 # . . push args +5496 68/push _test-output-buffered-file/imm32 +5497 68/push _test-input-stream/imm32 +5498 # . . call +5499 e8/call convert-instruction/disp32 +5500 # . . discard args +5501 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP +5502 # check output +5503 # . flush(_test-output-buffered-file) +5504 # . . push args +5505 68/push _test-output-buffered-file/imm32 +5506 # . . call +5507 e8/call flush/disp32 +5508 # . . discard args +5509 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP +5510 +-- 26 lines: #? # dump output --------------------------------------------------------------------------------------------------------------------------- +5536 # . check-stream-equal(_test-output-stream, "eb xyz/disp8 # eb/jump xyz/disp8", msg) +5537 # . . push args +5538 68/push "F - test-convert-instruction-handles-disp8-name"/imm32 +5539 68/push "eb xyz/disp8 # eb/jump xyz/disp8"/imm32 +5540 68/push _test-output-stream/imm32 +5541 # . . call +5542 e8/call check-stream-equal/disp32 +5543 # . . discard args +5544 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP +5545 # . epilog +5546 89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . . # copy EBP to ESP +5547 5d/pop-to-EBP +5548 c3/return +5549 +5550 test-convert-instruction-handles-imm32-operand: +5551 # expand /imm32 operand into 4 bytes +5552 # . prolog +5553 55/push-EBP +5554 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP +5555 # setup +5556 # . clear-stream(_test-input-stream) 5557 # . . push args -5558 68/push "e8/call 20/disp32"/imm32 -5559 68/push _test-input-stream/imm32 -5560 # . . call -5561 e8/call write/disp32 -5562 # . . discard args -5563 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP -5564 # convert-instruction(_test-input-stream, _test-output-buffered-file) -5565 # . . push args -5566 68/push _test-output-buffered-file/imm32 -5567 68/push _test-input-stream/imm32 -5568 # . . call -5569 e8/call convert-instruction/disp32 -5570 # . . discard args -5571 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP -5572 # check output -5573 # . flush(_test-output-buffered-file) -5574 # . . push args -5575 68/push _test-output-buffered-file/imm32 -5576 # . . call -5577 e8/call flush/disp32 -5578 # . . discard args -5579 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP -5580 +-- 34 lines: #? # dump output --------------------------------------------------------------------------------------------------------------------------- -5614 # . check-stream-equal(_test-output-stream, "e8 20 00 00 00 # e8/call 20/disp32", msg) -5615 # . . push args -5616 68/push "F - test-convert-instruction-handles-disp32-operand"/imm32 -5617 68/push "e8 20 00 00 00 # e8/call 20/disp32"/imm32 -5618 68/push _test-output-stream/imm32 -5619 # . . call -5620 e8/call check-stream-equal/disp32 -5621 # . . discard args -5622 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP -5623 # . epilog -5624 89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . . # copy EBP to ESP -5625 5d/pop-to-EBP -5626 c3/return -5627 -5628 test-convert-instruction-handles-disp16-operand: -5629 # expand /disp16 operand into 2 bytes -5630 # . prolog -5631 55/push-EBP -5632 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP -5633 # setup -5634 # . clear-stream(_test-input-stream) -5635 # . . push args -5636 68/push _test-input-stream/imm32 -5637 # . . call -5638 e8/call clear-stream/disp32 -5639 # . . discard args -5640 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP -5641 # . clear-stream(_test-output-stream) -5642 # . . push args -5643 68/push _test-output-stream/imm32 -5644 # . . call -5645 e8/call clear-stream/disp32 -5646 # . . discard args -5647 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP -5648 # . clear-stream(_test-output-buffered-file+4) -5649 # . . push args -5650 b8/copy-to-EAX _test-output-buffered-file/imm32 -5651 05/add-to-EAX 4/imm32 -5652 50/push-EAX -5653 # . . call -5654 e8/call clear-stream/disp32 -5655 # . . discard args -5656 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP -5657 # initialize input -5658 # . write(_test-input-stream, "e8/call 20/disp16") +5558 68/push _test-input-stream/imm32 +5559 # . . call +5560 e8/call clear-stream/disp32 +5561 # . . discard args +5562 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP +5563 # . clear-stream(_test-output-stream) +5564 # . . push args +5565 68/push _test-output-stream/imm32 +5566 # . . call +5567 e8/call clear-stream/disp32 +5568 # . . discard args +5569 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP +5570 # . clear-stream(_test-output-buffered-file+4) +5571 # . . push args +5572 b8/copy-to-EAX _test-output-buffered-file/imm32 +5573 05/add-to-EAX 4/imm32 +5574 50/push-EAX +5575 # . . call +5576 e8/call clear-stream/disp32 +5577 # . . discard args +5578 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP +5579 # initialize input +5580 # . write(_test-input-stream, "68/push 0x20/imm32") +5581 # . . push args +5582 68/push "68/push 0x20/imm32"/imm32 +5583 68/push _test-input-stream/imm32 +5584 # . . call +5585 e8/call write/disp32 +5586 # . . discard args +5587 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP +5588 # convert-instruction(_test-input-stream, _test-output-buffered-file) +5589 # . . push args +5590 68/push _test-output-buffered-file/imm32 +5591 68/push _test-input-stream/imm32 +5592 # . . call +5593 e8/call convert-instruction/disp32 +5594 # . . discard args +5595 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP +5596 # check output +5597 # . flush(_test-output-buffered-file) +5598 # . . push args +5599 68/push _test-output-buffered-file/imm32 +5600 # . . call +5601 e8/call flush/disp32 +5602 # . . discard args +5603 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP +5604 +-- 26 lines: #? # dump output --------------------------------------------------------------------------------------------------------------------------- +5630 # . check-stream-equal(_test-output-stream, "68 20 00 00 00 # 68/push 0x20/imm32", msg) +5631 # . . push args +5632 68/push "F - test-convert-instruction-handles-imm32-operand"/imm32 +5633 68/push "68 20 00 00 00 # 68/push 0x20/imm32"/imm32 +5634 68/push _test-output-stream/imm32 +5635 # . . call +5636 e8/call check-stream-equal/disp32 +5637 # . . discard args +5638 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP +5639 # . epilog +5640 89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . . # copy EBP to ESP +5641 5d/pop-to-EBP +5642 c3/return +5643 +5644 test-convert-instruction-handles-imm16-operand: +5645 # expand /imm16 operand into 2 bytes +5646 # we don't have one of these at the moment, so this expands to an invalid instruction +5647 # . prolog +5648 55/push-EBP +5649 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP +5650 # setup +5651 # . clear-stream(_test-input-stream) +5652 # . . push args +5653 68/push _test-input-stream/imm32 +5654 # . . call +5655 e8/call clear-stream/disp32 +5656 # . . discard args +5657 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP +5658 # . clear-stream(_test-output-stream) 5659 # . . push args -5660 68/push "e8/call 20/disp16"/imm32 # not a valid instruction -5661 68/push _test-input-stream/imm32 -5662 # . . call -5663 e8/call write/disp32 -5664 # . . discard args -5665 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP -5666 # convert-instruction(_test-input-stream, _test-output-buffered-file) -5667 # . . push args -5668 68/push _test-output-buffered-file/imm32 -5669 68/push _test-input-stream/imm32 +5660 68/push _test-output-stream/imm32 +5661 # . . call +5662 e8/call clear-stream/disp32 +5663 # . . discard args +5664 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP +5665 # . clear-stream(_test-output-buffered-file+4) +5666 # . . push args +5667 b8/copy-to-EAX _test-output-buffered-file/imm32 +5668 05/add-to-EAX 4/imm32 +5669 50/push-EAX 5670 # . . call -5671 e8/call convert-instruction/disp32 +5671 e8/call clear-stream/disp32 5672 # . . discard args -5673 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP -5674 # check output -5675 # . flush(_test-output-buffered-file) +5673 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP +5674 # initialize input +5675 # . write(_test-input-stream, "68/push 0x20/imm16") 5676 # . . push args -5677 68/push _test-output-buffered-file/imm32 -5678 # . . call -5679 e8/call flush/disp32 -5680 # . . discard args -5681 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP -5682 +-- 34 lines: #? # dump output --------------------------------------------------------------------------------------------------------------------------- -5716 # . check-stream-equal(_test-output-stream, "e8 20 00 # e8/call 20/disp16", msg) -5717 # . . push args -5718 68/push "F - test-convert-instruction-handles-disp16-operand"/imm32 -5719 68/push "e8 20 00 # e8/call 20/disp16"/imm32 -5720 68/push _test-output-stream/imm32 -5721 # . . call -5722 e8/call check-stream-equal/disp32 -5723 # . . discard args -5724 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP -5725 # . epilog -5726 89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . . # copy EBP to ESP -5727 5d/pop-to-EBP -5728 c3/return -5729 -5730 test-convert-instruction-handles-disp8-operand: -5731 # expand /disp8 operand into 1 byte -5732 # . prolog -5733 55/push-EBP -5734 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP -5735 # setup -5736 # . clear-stream(_test-input-stream) -5737 # . . push args -5738 68/push _test-input-stream/imm32 -5739 # . . call -5740 e8/call clear-stream/disp32 -5741 # . . discard args -5742 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP -5743 # . clear-stream(_test-output-stream) -5744 # . . push args -5745 68/push _test-output-stream/imm32 -5746 # . . call -5747 e8/call clear-stream/disp32 -5748 # . . discard args -5749 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP -5750 # . clear-stream(_test-output-buffered-file+4) -5751 # . . push args -5752 b8/copy-to-EAX _test-output-buffered-file/imm32 -5753 05/add-to-EAX 4/imm32 -5754 50/push-EAX -5755 # . . call -5756 e8/call clear-stream/disp32 -5757 # . . discard args -5758 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP -5759 # initialize input -5760 # . write(_test-input-stream, "eb/jump 20/disp8") +5677 68/push "68/push 0x20/imm16"/imm32 # not a valid instruction +5678 68/push _test-input-stream/imm32 +5679 # . . call +5680 e8/call write/disp32 +5681 # . . discard args +5682 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP +5683 # convert-instruction(_test-input-stream, _test-output-buffered-file) +5684 # . . push args +5685 68/push _test-output-buffered-file/imm32 +5686 68/push _test-input-stream/imm32 +5687 # . . call +5688 e8/call convert-instruction/disp32 +5689 # . . discard args +5690 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP +5691 # check output +5692 # . flush(_test-output-buffered-file) +5693 # . . push args +5694 68/push _test-output-buffered-file/imm32 +5695 # . . call +5696 e8/call flush/disp32 +5697 # . . discard args +5698 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP +5699 +-- 26 lines: #? # dump output --------------------------------------------------------------------------------------------------------------------------- +5725 # . check-stream-equal(_test-output-stream, "68 20 00 # 68/push 0x20/imm16", msg) +5726 # . . push args +5727 68/push "F - test-convert-instruction-handles-imm16-operand"/imm32 +5728 68/push "68 20 00 # 68/push 0x20/imm16"/imm32 +5729 68/push _test-output-stream/imm32 +5730 # . . call +5731 e8/call check-stream-equal/disp32 +5732 # . . discard args +5733 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP +5734 # . epilog +5735 89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . . # copy EBP to ESP +5736 5d/pop-to-EBP +5737 c3/return +5738 +5739 test-convert-instruction-handles-imm8-operand: +5740 # expand /imm8 operand into 1 byte +5741 # we don't have one of these at the moment, so this expands to an invalid instruction +5742 # . prolog +5743 55/push-EBP +5744 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP +5745 # setup +5746 # . clear-stream(_test-input-stream) +5747 # . . push args +5748 68/push _test-input-stream/imm32 +5749 # . . call +5750 e8/call clear-stream/disp32 +5751 # . . discard args +5752 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP +5753 # . clear-stream(_test-output-stream) +5754 # . . push args +5755 68/push _test-output-stream/imm32 +5756 # . . call +5757 e8/call clear-stream/disp32 +5758 # . . discard args +5759 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP +5760 # . clear-stream(_test-output-buffered-file+4) 5761 # . . push args -5762 68/push "eb/jump 20/disp8"/imm32 -5763 68/push _test-input-stream/imm32 -5764 # . . call -5765 e8/call write/disp32 -5766 # . . discard args -5767 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP -5768 # convert-instruction(_test-input-stream, _test-output-buffered-file) -5769 # . . push args -5770 68/push _test-output-buffered-file/imm32 -5771 68/push _test-input-stream/imm32 -5772 # . . call -5773 e8/call convert-instruction/disp32 -5774 # . . discard args -5775 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP -5776 # check output -5777 # . flush(_test-output-buffered-file) -5778 # . . push args -5779 68/push _test-output-buffered-file/imm32 -5780 # . . call -5781 e8/call flush/disp32 -5782 # . . discard args -5783 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP -5784 +-- 34 lines: #? # dump output --------------------------------------------------------------------------------------------------------------------------- -5818 # . check-stream-equal(_test-output-stream, "eb 20 # eb/jump 20/disp8", msg) -5819 # . . push args -5820 68/push "F - test-convert-instruction-handles-disp8-operand"/imm32 -5821 68/push "eb 20 # eb/jump 20/disp8"/imm32 -5822 68/push _test-output-stream/imm32 -5823 # . . call -5824 e8/call check-stream-equal/disp32 -5825 # . . discard args -5826 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP -5827 # . epilog -5828 89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . . # copy EBP to ESP -5829 5d/pop-to-EBP -5830 c3/return -5831 -5832 test-convert-instruction-handles-disp8-name: -5833 # pass /disp8 name directly through -5834 # . prolog -5835 55/push-EBP -5836 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP -5837 # setup -5838 # . clear-stream(_test-input-stream) -5839 # . . push args -5840 68/push _test-input-stream/imm32 -5841 # . . call -5842 e8/call clear-stream/disp32 -5843 # . . discard args -5844 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP -5845 # . clear-stream(_test-output-stream) -5846 # . . push args -5847 68/push _test-output-stream/imm32 -5848 # . . call -5849 e8/call clear-stream/disp32 -5850 # . . discard args -5851 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP -5852 # . clear-stream(_test-output-buffered-file+4) -5853 # . . push args -5854 b8/copy-to-EAX _test-output-buffered-file/imm32 -5855 05/add-to-EAX 4/imm32 -5856 50/push-EAX -5857 # . . call -5858 e8/call clear-stream/disp32 -5859 # . . discard args -5860 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP -5861 # initialize input -5862 # . write(_test-input-stream, "eb/jump xyz/disp8") -5863 # . . push args -5864 68/push "eb/jump xyz/disp8"/imm32 -5865 68/push _test-input-stream/imm32 -5866 # . . call -5867 e8/call write/disp32 -5868 # . . discard args -5869 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP -5870 # convert-instruction(_test-input-stream, _test-output-buffered-file) -5871 # . . push args -5872 68/push _test-output-buffered-file/imm32 -5873 68/push _test-input-stream/imm32 -5874 # . . call -5875 e8/call convert-instruction/disp32 -5876 # . . discard args -5877 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP -5878 # check output -5879 # . flush(_test-output-buffered-file) -5880 # . . push args -5881 68/push _test-output-buffered-file/imm32 -5882 # . . call -5883 e8/call flush/disp32 -5884 # . . discard args -5885 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP -5886 +-- 34 lines: #? # dump output --------------------------------------------------------------------------------------------------------------------------- -5920 # . check-stream-equal(_test-output-stream, "eb xyz/disp8 # eb/jump xyz/disp8", msg) -5921 # . . push args -5922 68/push "F - test-convert-instruction-handles-disp8-name"/imm32 -5923 68/push "eb xyz/disp8 # eb/jump xyz/disp8"/imm32 -5924 68/push _test-output-stream/imm32 -5925 # . . call -5926 e8/call check-stream-equal/disp32 -5927 # . . discard args -5928 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP -5929 # . epilog -5930 89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . . # copy EBP to ESP -5931 5d/pop-to-EBP -5932 c3/return -5933 -5934 test-convert-instruction-handles-imm32-operand: -5935 # expand /imm32 operand into 4 bytes -5936 # . prolog -5937 55/push-EBP -5938 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP -5939 # setup -5940 # . clear-stream(_test-input-stream) -5941 # . . push args -5942 68/push _test-input-stream/imm32 -5943 # . . call -5944 e8/call clear-stream/disp32 -5945 # . . discard args -5946 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP -5947 # . clear-stream(_test-output-stream) -5948 # . . push args -5949 68/push _test-output-stream/imm32 -5950 # . . call -5951 e8/call clear-stream/disp32 -5952 # . . discard args -5953 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP -5954 # . clear-stream(_test-output-buffered-file+4) -5955 # . . push args -5956 b8/copy-to-EAX _test-output-buffered-file/imm32 -5957 05/add-to-EAX 4/imm32 -5958 50/push-EAX -5959 # . . call -5960 e8/call clear-stream/disp32 -5961 # . . discard args -5962 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP -5963 # initialize input -5964 # . write(_test-input-stream, "68/push 0x20/imm32") -5965 # . . push args -5966 68/push "68/push 0x20/imm32"/imm32 -5967 68/push _test-input-stream/imm32 -5968 # . . call -5969 e8/call write/disp32 -5970 # . . discard args -5971 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP -5972 # convert-instruction(_test-input-stream, _test-output-buffered-file) -5973 # . . push args -5974 68/push _test-output-buffered-file/imm32 -5975 68/push _test-input-stream/imm32 -5976 # . . call -5977 e8/call convert-instruction/disp32 -5978 # . . discard args -5979 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP -5980 # check output -5981 # . flush(_test-output-buffered-file) -5982 # . . push args -5983 68/push _test-output-buffered-file/imm32 -5984 # . . call -5985 e8/call flush/disp32 -5986 # . . discard args -5987 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP -5988 +-- 34 lines: #? # dump output --------------------------------------------------------------------------------------------------------------------------- -6022 # . check-stream-equal(_test-output-stream, "68 20 00 00 00 # 68/push 0x20/imm32", msg) -6023 # . . push args -6024 68/push "F - test-convert-instruction-handles-imm32-operand"/imm32 -6025 68/push "68 20 00 00 00 # 68/push 0x20/imm32"/imm32 -6026 68/push _test-output-stream/imm32 -6027 # . . call -6028 e8/call check-stream-equal/disp32 -6029 # . . discard args -6030 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP -6031 # . epilog -6032 89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . . # copy EBP to ESP -6033 5d/pop-to-EBP -6034 c3/return -6035 -6036 test-convert-instruction-handles-imm16-operand: -6037 # expand /imm16 operand into 2 bytes -6038 # we don't have one of these at the moment, so this expands to an invalid instruction +5762 b8/copy-to-EAX _test-output-buffered-file/imm32 +5763 05/add-to-EAX 4/imm32 +5764 50/push-EAX +5765 # . . call +5766 e8/call clear-stream/disp32 +5767 # . . discard args +5768 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP +5769 # initialize input +5770 # . write(_test-input-stream, "68/push 0x20/imm8") +5771 # . . push args +5772 68/push "68/push 0x20/imm8"/imm32 +5773 68/push _test-input-stream/imm32 +5774 # . . call +5775 e8/call write/disp32 +5776 # . . discard args +5777 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP +5778 # convert-instruction(_test-input-stream, _test-output-buffered-file) +5779 # . . push args +5780 68/push _test-output-buffered-file/imm32 +5781 68/push _test-input-stream/imm32 +5782 # . . call +5783 e8/call convert-instruction/disp32 +5784 # . . discard args +5785 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP +5786 # check output +5787 # . flush(_test-output-buffered-file) +5788 # . . push args +5789 68/push _test-output-buffered-file/imm32 +5790 # . . call +5791 e8/call flush/disp32 +5792 # . . discard args +5793 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP +5794 +-- 26 lines: #? # dump output --------------------------------------------------------------------------------------------------------------------------- +5820 # . check-stream-equal(_test-output-stream, "68 20 # 68/push 0x20/imm8", msg) +5821 # . . push args +5822 68/push "F - test-convert-instruction-handles-imm8-operand"/imm32 +5823 68/push "68 20 # 68/push 0x20/imm8"/imm32 +5824 68/push _test-output-stream/imm32 +5825 # . . call +5826 e8/call check-stream-equal/disp32 +5827 # . . discard args +5828 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP +5829 # . epilog +5830 89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . . # copy EBP to ESP +5831 5d/pop-to-EBP +5832 c3/return +5833 +5834 # (re)compute the bounds of the next word in the line +5835 # return empty string on reaching end of file +5836 next-word: # line : (address stream byte), out : (address slice) +5837 # . prolog +5838 55/push-EBP +5839 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP +5840 # . save registers +5841 50/push-EAX +5842 51/push-ECX +5843 56/push-ESI +5844 57/push-EDI +5845 # ESI = line +5846 8b/copy 1/mod/*+disp8 5/rm32/EBP . . . 6/r32/ESI 8/disp8 . # copy *(EBP+8) to ESI +5847 # EDI = out +5848 8b/copy 1/mod/*+disp8 5/rm32/EBP . . . 7/r32/EDI 0xc/disp8 . # copy *(EBP+12) to EDI +5849 # skip-chars-matching(line, ' ') +5850 # . . push args +5851 68/push 0x20/imm32/space +5852 ff 6/subop/push 1/mod/*+disp8 5/rm32/EBP . . . . 8/disp8 . # push *(EBP+8) +5853 # . . call +5854 e8/call skip-chars-matching/disp32 +5855 # . . discard args +5856 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP +5857 $next-word:check0: +5858 # if (line->read >= line->write) clear out and return +5859 # . EAX = line->read +5860 8b/copy 1/mod/*+disp8 6/rm32/ESI . . . 0/r32/EAX 4/disp8 . # copy *(ESI+4) to EAX +5861 # . if (EAX < line->write) goto next check +5862 3b/compare 0/mod/indirect 6/rm32/ESI . . . 0/r32/EAX . . # compare EAX with *ESI +5863 7c/jump-if-lesser $next-word:check-for-comment/disp8 +5864 # . return out = {0, 0} +5865 c7 0/subop/copy 0/mod/direct 7/rm32/EDI . . . . . 0/imm32 # copy to *EDI +5866 c7 0/subop/copy 1/mod/*+disp8 7/rm32/EDI . . . . 4/disp8 0/imm32 # copy to *(EDI+4) +5867 eb/jump $next-word:end/disp8 +5868 $next-word:check-for-comment: +5869 # out->start = &line->data[line->read] +5870 8b/copy 1/mod/*+disp8 6/rm32/ESI . . . 1/r32/ECX 4/disp8 . # copy *(ESI+4) to ECX +5871 8d/copy-address 1/mod/*+disp8 4/rm32/sib 6/base/ESI 1/index/ECX . 0/r32/EAX 0xc/disp8 . # copy ESI+ECX+12 to EAX +5872 89/copy 0/mod/indirect 7/rm32/EDI . . . 0/r32/EAX . . # copy EAX to *EDI +5873 # if (line->data[line->read] == '#') out->end = &line->data[line->write]), skip rest of stream and return +5874 # . EAX = line->data[line->read] +5875 31/xor 3/mod/direct 0/rm32/EAX . . . 0/r32/EAX . . # clear EAX +5876 8a/copy-byte 1/mod/*+disp8 4/rm32/sib 6/base/ESI 1/index/ECX . 0/r32/AL 0xc/disp8 . # copy byte at *(ESI+ECX+12) to AL +5877 # . compare +5878 3d/compare-EAX-and 0x23/imm32/pound +5879 75/jump-if-not-equal $next-word:regular-word/disp8 +5880 $next-word:comment: +5881 # . out->end = &line->data[line->write] +5882 8b/copy 0/mod/indirect 6/rm32/ESI . . . 0/r32/EAX . . # copy *ESI to EAX +5883 8d/copy-address 1/mod/*+disp8 4/rm32/sib 6/base/ESI 0/index/EAX . 0/r32/EAX 0xc/disp8 . # copy ESI+EAX+12 to EAX +5884 89/copy 1/mod/*+disp8 7/rm32/EDI . . . 0/r32/EAX 4/disp8 . # copy EAX to *(EDI+4) +5885 # . line->read = line->write +5886 89/copy 1/mod/*+disp8 6/rm32/ESI . . . 0/r32/EAX 4/disp8 . # copy EAX to *(ESI+4) +5887 # . return +5888 eb/jump $next-word:end/disp8 +5889 $next-word:regular-word: +5890 # otherwise skip-chars-not-matching-whitespace(line) # including trailing newline +5891 # . . push args +5892 ff 6/subop/push 1/mod/*+disp8 5/rm32/EBP . . . . 8/disp8 . # push *(EBP+8) +5893 # . . call +5894 e8/call skip-chars-not-matching-whitespace/disp32 +5895 # . . discard args +5896 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP +5897 # out->end = &line->data[line->read] +5898 8b/copy 1/mod/*+disp8 6/rm32/ESI . . . 1/r32/ECX 4/disp8 . # copy *(ESI+4) to ECX +5899 8d/copy-address 1/mod/*+disp8 4/rm32/sib 6/base/ESI 1/index/ECX . 0/r32/EAX 0xc/disp8 . # copy ESI+ECX+12 to EAX +5900 89/copy 1/mod/*+disp8 7/rm32/EDI . . . 0/r32/EAX 4/disp8 . # copy EAX to *(EDI+4) +5901 $next-word:end: +5902 # . restore registers +5903 5f/pop-to-EDI +5904 5e/pop-to-ESI +5905 59/pop-to-ECX +5906 58/pop-to-EAX +5907 # . epilog +5908 89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . . # copy EBP to ESP +5909 5d/pop-to-EBP +5910 c3/return +5911 +5912 test-next-word: +5913 # . prolog +5914 55/push-EBP +5915 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP +5916 # setup +5917 # . clear-stream(_test-stream) +5918 # . . push args +5919 68/push _test-stream/imm32 +5920 # . . call +5921 e8/call clear-stream/disp32 +5922 # . . discard args +5923 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP +5924 # var slice/ECX = {0, 0} +5925 68/push 0/imm32/end +5926 68/push 0/imm32/start +5927 89/copy 3/mod/direct 1/rm32/ECX . . . 4/r32/ESP . . # copy ESP to ECX +5928 # write(_test-stream, " ab") +5929 # . . push args +5930 68/push " ab"/imm32 +5931 68/push _test-stream/imm32 +5932 # . . call +5933 e8/call write/disp32 +5934 # . . discard args +5935 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP +5936 # next-word(_test-stream, slice) +5937 # . . push args +5938 51/push-ECX +5939 68/push _test-stream/imm32 +5940 # . . call +5941 e8/call next-word/disp32 +5942 # . . discard args +5943 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP +5944 # check-ints-equal(slice->start - _test-stream->data, 2, msg) +5945 # . check-ints-equal(slice->start - _test-stream, 14, msg) +5946 # . . push args +5947 68/push "F - test-next-word: start"/imm32 +5948 68/push 0xe/imm32 +5949 # . . push slice->start - _test-stream +5950 8b/copy 0/mod/indirect 1/rm32/ECX . . . 0/r32/EAX . . # copy *ECX to EAX +5951 81 5/subop/subtract 3/mod/direct 0/rm32/EAX . . . . . _test-stream/imm32 # subtract from EAX +5952 50/push-EAX +5953 # . . call +5954 e8/call check-ints-equal/disp32 +5955 # . . discard args +5956 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP +5957 # check-ints-equal(slice->end - _test-stream->data, 4, msg) +5958 # . check-ints-equal(slice->end - _test-stream, 16, msg) +5959 # . . push args +5960 68/push "F - test-next-word: end"/imm32 +5961 68/push 0x10/imm32 +5962 # . . push slice->end - _test-stream +5963 8b/copy 1/mod/*+disp8 1/rm32/ECX . . . 0/r32/EAX 4/disp8 . # copy *(ECX+4) to EAX +5964 81 5/subop/subtract 3/mod/direct 0/rm32/EAX . . . . . _test-stream/imm32 # subtract from EAX +5965 50/push-EAX +5966 # . . call +5967 e8/call check-ints-equal/disp32 +5968 # . . discard args +5969 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP +5970 # . epilog +5971 89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . . # copy EBP to ESP +5972 5d/pop-to-EBP +5973 c3/return +5974 +5975 test-next-word-returns-whole-comment: +5976 # . prolog +5977 55/push-EBP +5978 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP +5979 # setup +5980 # . clear-stream(_test-stream) +5981 # . . push args +5982 68/push _test-stream/imm32 +5983 # . . call +5984 e8/call clear-stream/disp32 +5985 # . . discard args +5986 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP +5987 # var slice/ECX = {0, 0} +5988 68/push 0/imm32/end +5989 68/push 0/imm32/start +5990 89/copy 3/mod/direct 1/rm32/ECX . . . 4/r32/ESP . . # copy ESP to ECX +5991 # write(_test-stream, " # a") +5992 # . . push args +5993 68/push " # a"/imm32 +5994 68/push _test-stream/imm32 +5995 # . . call +5996 e8/call write/disp32 +5997 # . . discard args +5998 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP +5999 # next-word(_test-stream, slice) +6000 # . . push args +6001 51/push-ECX +6002 68/push _test-stream/imm32 +6003 # . . call +6004 e8/call next-word/disp32 +6005 # . . discard args +6006 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP +6007 # check-ints-equal(slice->start - _test-stream->data, 2, msg) +6008 # . check-ints-equal(slice->start - _test-stream, 14, msg) +6009 # . . push args +6010 68/push "F - test-next-word-returns-whole-comment: start"/imm32 +6011 68/push 0xe/imm32 +6012 # . . push slice->start - _test-stream +6013 8b/copy 0/mod/indirect 1/rm32/ECX . . . 0/r32/EAX . . # copy *ECX to EAX +6014 81 5/subop/subtract 3/mod/direct 0/rm32/EAX . . . . . _test-stream/imm32 # subtract from EAX +6015 50/push-EAX +6016 # . . call +6017 e8/call check-ints-equal/disp32 +6018 # . . discard args +6019 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP +6020 # check-ints-equal(slice->end - _test-stream->data, 5, msg) +6021 # . check-ints-equal(slice->end - _test-stream, 17, msg) +6022 # . . push args +6023 68/push "F - test-next-word-returns-whole-comment: end"/imm32 +6024 68/push 0x11/imm32 +6025 # . . push slice->end - _test-stream +6026 8b/copy 1/mod/*+disp8 1/rm32/ECX . . . 0/r32/EAX 4/disp8 . # copy *(ECX+4) to EAX +6027 81 5/subop/subtract 3/mod/direct 0/rm32/EAX . . . . . _test-stream/imm32 # subtract from EAX +6028 50/push-EAX +6029 # . . call +6030 e8/call check-ints-equal/disp32 +6031 # . . discard args +6032 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP +6033 # . epilog +6034 89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . . # copy EBP to ESP +6035 5d/pop-to-EBP +6036 c3/return +6037 +6038 test-next-word-returns-empty-string-on-eof: 6039 # . prolog 6040 55/push-EBP 6041 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP 6042 # setup -6043 # . clear-stream(_test-input-stream) +6043 # . clear-stream(_test-stream) 6044 # . . push args -6045 68/push _test-input-stream/imm32 +6045 68/push _test-stream/imm32 6046 # . . call 6047 e8/call clear-stream/disp32 6048 # . . discard args 6049 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP -6050 # . clear-stream(_test-output-stream) -6051 # . . push args -6052 68/push _test-output-stream/imm32 -6053 # . . call -6054 e8/call clear-stream/disp32 -6055 # . . discard args -6056 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP -6057 # . clear-stream(_test-output-buffered-file+4) -6058 # . . push args -6059 b8/copy-to-EAX _test-output-buffered-file/imm32 -6060 05/add-to-EAX 4/imm32 -6061 50/push-EAX -6062 # . . call -6063 e8/call clear-stream/disp32 -6064 # . . discard args -6065 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP -6066 # initialize input -6067 # . write(_test-input-stream, "68/push 0x20/imm16") -6068 # . . push args -6069 68/push "68/push 0x20/imm16"/imm32 # not a valid instruction -6070 68/push _test-input-stream/imm32 +6050 # var slice/ECX = {0, 0} +6051 68/push 0/imm32/end +6052 68/push 0/imm32/start +6053 89/copy 3/mod/direct 1/rm32/ECX . . . 4/r32/ESP . . # copy ESP to ECX +6054 # write nothing to _test-stream +6055 # next-word(_test-stream, slice) +6056 # . . push args +6057 51/push-ECX +6058 68/push _test-stream/imm32 +6059 # . . call +6060 e8/call next-word/disp32 +6061 # . . discard args +6062 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP +6063 # check-ints-equal(slice->end - slice->start, 0, msg) +6064 # . . push args +6065 68/push "F - test-next-word-returns-empty-string-on-eof"/imm32 +6066 68/push 0/imm32 +6067 # . . push slice->end - slice->start +6068 8b/copy 1/mod/*+disp8 1/rm32/ECX . . . 0/r32/EAX 4/disp8 . # copy *(ECX+4) to EAX +6069 2b/subtract 0/mod/indirect 1/rm32/ECX . . . 0/r32/EAX . . # subtract *ECX from EAX +6070 50/push-EAX 6071 # . . call -6072 e8/call write/disp32 +6072 e8/call check-ints-equal/disp32 6073 # . . discard args -6074 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP -6075 # convert-instruction(_test-input-stream, _test-output-buffered-file) -6076 # . . push args -6077 68/push _test-output-buffered-file/imm32 -6078 68/push _test-input-stream/imm32 -6079 # . . call -6080 e8/call convert-instruction/disp32 -6081 # . . discard args -6082 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP -6083 # check output -6084 # . flush(_test-output-buffered-file) -6085 # . . push args -6086 68/push _test-output-buffered-file/imm32 -6087 # . . call -6088 e8/call flush/disp32 -6089 # . . discard args -6090 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP -6091 +-- 34 lines: #? # dump output --------------------------------------------------------------------------------------------------------------------------- -6125 # . check-stream-equal(_test-output-stream, "68 20 00 # 68/push 0x20/imm16", msg) -6126 # . . push args -6127 68/push "F - test-convert-instruction-handles-imm16-operand"/imm32 -6128 68/push "68 20 00 # 68/push 0x20/imm16"/imm32 -6129 68/push _test-output-stream/imm32 -6130 # . . call -6131 e8/call check-stream-equal/disp32 -6132 # . . discard args -6133 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP -6134 # . epilog -6135 89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . . # copy EBP to ESP -6136 5d/pop-to-EBP -6137 c3/return -6138 -6139 test-convert-instruction-handles-imm8-operand: -6140 # expand /imm8 operand into 1 byte -6141 # we don't have one of these at the moment, so this expands to an invalid instruction -6142 # . prolog -6143 55/push-EBP -6144 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP -6145 # setup -6146 # . clear-stream(_test-input-stream) -6147 # . . push args -6148 68/push _test-input-stream/imm32 -6149 # . . call -6150 e8/call clear-stream/disp32 -6151 # . . discard args -6152 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP -6153 # . clear-stream(_test-output-stream) -6154 # . . push args -6155 68/push _test-output-stream/imm32 -6156 # . . call -6157 e8/call clear-stream/disp32 -6158 # . . discard args -6159 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP -6160 # . clear-stream(_test-output-buffered-file+4) -6161 # . . push args -6162 b8/copy-to-EAX _test-output-buffered-file/imm32 -6163 05/add-to-EAX 4/imm32 -6164 50/push-EAX -6165 # . . call -6166 e8/call clear-stream/disp32 -6167 # . . discard args -6168 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP -6169 # initialize input -6170 # . write(_test-input-stream, "68/push 0x20/imm8") -6171 # . . push args -6172 68/push "68/push 0x20/imm8"/imm32 -6173 68/push _test-input-stream/imm32 -6174 # . . call -6175 e8/call write/disp32 -6176 # . . discard args -6177 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP -6178 # convert-instruction(_test-input-stream, _test-output-buffered-file) -6179 # . . push args -6180 68/push _test-output-buffered-file/imm32 -6181 68/push _test-input-stream/imm32 -6182 # . . call -6183 e8/call convert-instruction/disp32 -6184 # . . discard args -6185 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP -6186 # check output -6187 # . flush(_test-output-buffered-file) -6188 # . . push args -6189 68/push _test-output-buffered-file/imm32 +6074 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP +6075 # . epilog +6076 89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . . # copy EBP to ESP +6077 5d/pop-to-EBP +6078 c3/return +6079 +6080 has-metadata?: # word : (address slice), s : (address string) -> EAX : boolean +6081 # pseudocode: +6082 # var twig : &slice = next-token-from-slice(word->start, word->end, '/') # skip name +6083 # curr = twig->end +6084 # while true +6085 # twig = next-token-from-slice(curr, word->end, '/') +6086 # if (twig.empty()) break +6087 # if (slice-equal?(twig, s)) return true +6088 # curr = twig->end +6089 # return false +6090 # . prolog +6091 55/push-EBP +6092 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP +6093 # . save registers +6094 51/push-ECX +6095 52/push-EDX +6096 56/push-ESI +6097 57/push-EDI +6098 # ESI = word +6099 8b/copy 1/mod/*+disp8 5/rm32/EBP . . . 6/r32/ESI 8/disp8 . # copy *(EBP+8) to ESI +6100 # EDX = word->end +6101 8b/copy 1/mod/*+disp8 6/rm32/ESI . . . 2/r32/EDX 4/disp8 . # copy *(ESI+4) to EDX +6102 # var twig/EDI : (address slice) = {0, 0} +6103 68/push 0/imm32/end +6104 68/push 0/imm32/start +6105 89/copy 3/mod/direct 7/rm32/EDI . . . 4/r32/ESP . . # copy ESP to EDI +6106 # next-token-from-slice(word->start, word->end, '/', twig) +6107 # . . push args +6108 57/push-EDI +6109 68/push 0x2f/imm32/slash +6110 52/push-EDX +6111 ff 6/subop/push 0/mod/indirect 6/rm32/ESI . . . . . . # push *ESI +6112 # . . call +6113 e8/call next-token-from-slice/disp32 +6114 # . . discard args +6115 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0x10/imm32 # add to ESP +6116 # curr/ECX = twig->end +6117 8b/copy 1/mod/*+disp8 7/rm32/EDI . . . 1/r32/ECX 4/disp8 . # copy *(EDI+4) to ECX +6118 $has-metadata?:loop: +6119 # next-token-from-slice(curr, word->end, '/', twig) +6120 # . . push args +6121 57/push-EDI +6122 68/push 0x2f/imm32/slash +6123 52/push-EDX +6124 51/push-ECX +6125 # . . call +6126 e8/call next-token-from-slice/disp32 +6127 # . . discard args +6128 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0x10/imm32 # add to ESP +6129 # if (slice-empty?(twig)) return false +6130 # . EAX = slice-empty?(twig) +6131 # . . push args +6132 57/push-EDI +6133 # . . call +6134 e8/call slice-empty?/disp32 +6135 # . . discard args +6136 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP +6137 # . if (EAX != 0) return false +6138 3d/compare-EAX-and 0/imm32 +6139 75/jump-if-not-equal $has-metadata?:false/disp8 +6140 # if (slice-equal?(twig, s)) return true +6141 # . EAX = slice-equal?(twig, s) +6142 # . . push args +6143 ff 6/subop/push 1/mod/*+disp8 5/rm32/EBP . . . . 0xc/disp8 . # push *(EBP+12) +6144 57/push-EDI +6145 # . . call +6146 e8/call slice-equal?/disp32 +6147 # . . discard args +6148 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP +6149 # . if (EAX != 0) return true +6150 3d/compare-EAX-and 0/imm32 +6151 75/jump-if-not-equal $has-metadata?:true/disp8 +6152 # curr = twig->end +6153 8b/copy 1/mod/*+disp8 7/rm32/EDI . . . 1/r32/ECX 4/disp8 . # copy *(EDI+4) to ECX +6154 eb/jump $has-metadata?:loop/disp8 +6155 $has-metadata?:true: +6156 b8/copy-to-EAX 1/imm32/true +6157 eb/jump $has-metadata?:end/disp8 +6158 $has-metadata?:false: +6159 b8/copy-to-EAX 0/imm32/false +6160 $has-metadata?:end: +6161 # . reclaim locals +6162 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP +6163 # . restore registers +6164 5f/pop-to-EDI +6165 5e/pop-to-ESI +6166 5a/pop-to-EDX +6167 59/pop-to-ECX +6168 # . epilog +6169 89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . . # copy EBP to ESP +6170 5d/pop-to-EBP +6171 c3/return +6172 +6173 test-has-metadata-true: +6174 # . prolog +6175 55/push-EBP +6176 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP +6177 # (EAX..ECX) = "ab/c" +6178 b8/copy-to-EAX "ab/c"/imm32 +6179 8b/copy 0/mod/indirect 0/rm32/EAX . . . 1/r32/ECX . . # copy *EAX to ECX +6180 8d/copy-address 1/mod/*+disp8 4/rm32/sib 0/base/EAX 1/index/ECX . 1/r32/ECX 4/disp8 . # copy EAX+ECX+4 to ECX +6181 05/add-to-EAX 4/imm32 +6182 # var in/ESI : (address slice) = {EAX, ECX} +6183 51/push-ECX +6184 50/push-EAX +6185 89/copy 3/mod/direct 6/rm32/ESI . . . 4/r32/ESP . . # copy ESP to ESI +6186 # EAX = has-metadata?(ESI, "c") +6187 # . . push args +6188 68/push "c"/imm32 +6189 56/push-ESI 6190 # . . call -6191 e8/call flush/disp32 +6191 e8/call has-metadata?/disp32 6192 # . . discard args -6193 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP -6194 +-- 34 lines: #? # dump output --------------------------------------------------------------------------------------------------------------------------- -6228 # . check-stream-equal(_test-output-stream, "68 20 # 68/push 0x20/imm8", msg) -6229 # . . push args -6230 68/push "F - test-convert-instruction-handles-imm8-operand"/imm32 -6231 68/push "68 20 # 68/push 0x20/imm8"/imm32 -6232 68/push _test-output-stream/imm32 -6233 # . . call -6234 e8/call check-stream-equal/disp32 -6235 # . . discard args -6236 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP -6237 # . epilog -6238 89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . . # copy EBP to ESP -6239 5d/pop-to-EBP -6240 c3/return -6241 -6242 has-metadata?: # word : (address slice), s : (address string) -> EAX : boolean -6243 # pseudocode: -6244 # var twig : &slice = next-token-from-slice(word->start, word->end, '/') # skip name -6245 # curr = twig->end -6246 # while true -6247 # twig = next-token-from-slice(curr, word->end, '/') -6248 # if (twig.empty()) break -6249 # if (slice-equal?(twig, s)) return true -6250 # curr = twig->end -6251 # return false -6252 # . prolog -6253 55/push-EBP -6254 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP -6255 # . save registers -6256 51/push-ECX -6257 52/push-EDX -6258 56/push-ESI -6259 57/push-EDI -6260 # ESI = word -6261 8b/copy 1/mod/*+disp8 5/rm32/EBP . . . 6/r32/ESI 8/disp8 . # copy *(EBP+8) to ESI -6262 # EDX = word->end -6263 8b/copy 1/mod/*+disp8 6/rm32/ESI . . . 2/r32/EDX 4/disp8 . # copy *(ESI+4) to EDX -6264 # var twig/EDI : (address slice) = {0, 0} -6265 68/push 0/imm32/end -6266 68/push 0/imm32/start -6267 89/copy 3/mod/direct 7/rm32/EDI . . . 4/r32/ESP . . # copy ESP to EDI -6268 # next-token-from-slice(word->start, word->end, '/', twig) -6269 # . . push args -6270 57/push-EDI -6271 68/push 0x2f/imm32/slash -6272 52/push-EDX -6273 ff 6/subop/push 0/mod/indirect 6/rm32/ESI . . . . . . # push *ESI -6274 # . . call -6275 e8/call next-token-from-slice/disp32 -6276 # . . discard args -6277 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0x10/imm32 # add to ESP -6278 # curr/ECX = twig->end -6279 8b/copy 1/mod/*+disp8 7/rm32/EDI . . . 1/r32/ECX 4/disp8 . # copy *(EDI+4) to ECX -6280 $has-metadata?:loop: -6281 # next-token-from-slice(curr, word->end, '/', twig) -6282 # . . push args -6283 57/push-EDI -6284 68/push 0x2f/imm32/slash -6285 52/push-EDX -6286 51/push-ECX -6287 # . . call -6288 e8/call next-token-from-slice/disp32 -6289 # . . discard args -6290 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0x10/imm32 # add to ESP -6291 # if (slice-empty?(twig)) return false -6292 # . EAX = slice-empty?(twig) -6293 # . . push args -6294 57/push-EDI +6193 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP +6194 # check-ints-equal(EAX, 1, msg) +6195 # . . push args +6196 68/push "F - test-has-metadata-true"/imm32 +6197 68/push 1/imm32/true +6198 50/push-EAX +6199 # . . call +6200 e8/call check-ints-equal/disp32 +6201 # . . discard args +6202 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP +6203 # . epilog +6204 89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . . # copy EBP to ESP +6205 5d/pop-to-EBP +6206 c3/return +6207 +6208 test-has-metadata-false: +6209 # . prolog +6210 55/push-EBP +6211 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP +6212 # (EAX..ECX) = "ab/c" +6213 b8/copy-to-EAX "ab/c"/imm32 +6214 8b/copy 0/mod/indirect 0/rm32/EAX . . . 1/r32/ECX . . # copy *EAX to ECX +6215 8d/copy-address 1/mod/*+disp8 4/rm32/sib 0/base/EAX 1/index/ECX . 1/r32/ECX 4/disp8 . # copy EAX+ECX+4 to ECX +6216 05/add-to-EAX 4/imm32 +6217 # var in/ESI : (address slice) = {EAX, ECX} +6218 51/push-ECX +6219 50/push-EAX +6220 89/copy 3/mod/direct 6/rm32/ESI . . . 4/r32/ESP . . # copy ESP to ESI +6221 # EAX = has-metadata?(ESI, "c") +6222 # . . push args +6223 68/push "d"/imm32 +6224 56/push-ESI +6225 # . . call +6226 e8/call has-metadata?/disp32 +6227 # . . discard args +6228 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP +6229 # check-ints-equal(EAX, 0, msg) +6230 # . . push args +6231 68/push "F - test-has-metadata-false"/imm32 +6232 68/push 0/imm32/false +6233 50/push-EAX +6234 # . . call +6235 e8/call check-ints-equal/disp32 +6236 # . . discard args +6237 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP +6238 # . epilog +6239 89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . . # copy EBP to ESP +6240 5d/pop-to-EBP +6241 c3/return +6242 +6243 test-has-metadata-ignore-name: +6244 # . prolog +6245 55/push-EBP +6246 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP +6247 # (EAX..ECX) = "a/b" +6248 b8/copy-to-EAX "a/b"/imm32 +6249 8b/copy 0/mod/indirect 0/rm32/EAX . . . 1/r32/ECX . . # copy *EAX to ECX +6250 8d/copy-address 1/mod/*+disp8 4/rm32/sib 0/base/EAX 1/index/ECX . 1/r32/ECX 4/disp8 . # copy EAX+ECX+4 to ECX +6251 05/add-to-EAX 4/imm32 +6252 # var in/ESI : (address slice) = {EAX, ECX} +6253 51/push-ECX +6254 50/push-EAX +6255 89/copy 3/mod/direct 6/rm32/ESI . . . 4/r32/ESP . . # copy ESP to ESI +6256 # EAX = has-metadata?(ESI, "a") +6257 # . . push args +6258 68/push "a"/imm32 +6259 56/push-ESI +6260 # . . call +6261 e8/call has-metadata?/disp32 +6262 # . . discard args +6263 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP +6264 # check-ints-equal(EAX, 0, msg) +6265 # . . push args +6266 68/push "F - test-has-metadata-ignore-name"/imm32 +6267 68/push 0/imm32/false +6268 50/push-EAX +6269 # . . call +6270 e8/call check-ints-equal/disp32 +6271 # . . discard args +6272 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP +6273 # . epilog +6274 89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . . # copy EBP to ESP +6275 5d/pop-to-EBP +6276 c3/return +6277 +6278 test-has-metadata-multiple-true: +6279 # . prolog +6280 55/push-EBP +6281 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP +6282 # (EAX..ECX) = "a/b/c" +6283 b8/copy-to-EAX "a/b/c"/imm32 +6284 8b/copy 0/mod/indirect 0/rm32/EAX . . . 1/r32/ECX . . # copy *EAX to ECX +6285 8d/copy-address 1/mod/*+disp8 4/rm32/sib 0/base/EAX 1/index/ECX . 1/r32/ECX 4/disp8 . # copy EAX+ECX+4 to ECX +6286 05/add-to-EAX 4/imm32 +6287 # var in/ESI : (address slice) = {EAX, ECX} +6288 51/push-ECX +6289 50/push-EAX +6290 89/copy 3/mod/direct 6/rm32/ESI . . . 4/r32/ESP . . # copy ESP to ESI +6291 # EAX = has-metadata?(ESI, "c") +6292 # . . push args +6293 68/push "c"/imm32 +6294 56/push-ESI 6295 # . . call -6296 e8/call slice-empty?/disp32 +6296 e8/call has-metadata?/disp32 6297 # . . discard args -6298 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP -6299 # . if (EAX != 0) return false -6300 3d/compare-EAX-and 0/imm32 -6301 75/jump-if-not-equal $has-metadata?:false/disp8 -6302 # if (slice-equal?(twig, s)) return true -6303 # . EAX = slice-equal?(twig, s) -6304 # . . push args -6305 ff 6/subop/push 1/mod/*+disp8 5/rm32/EBP . . . . 0xc/disp8 . # push *(EBP+12) -6306 57/push-EDI -6307 # . . call -6308 e8/call slice-equal?/disp32 -6309 # . . discard args -6310 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP -6311 # . if (EAX != 0) return true -6312 3d/compare-EAX-and 0/imm32 -6313 75/jump-if-not-equal $has-metadata?:true/disp8 -6314 # curr = twig->end -6315 8b/copy 1/mod/*+disp8 7/rm32/EDI . . . 1/r32/ECX 4/disp8 . # copy *(EDI+4) to ECX -6316 eb/jump $has-metadata?:loop/disp8 -6317 $has-metadata?:true: -6318 b8/copy-to-EAX 1/imm32/true -6319 eb/jump $has-metadata?:end/disp8 -6320 $has-metadata?:false: -6321 b8/copy-to-EAX 0/imm32/false -6322 $has-metadata?:end: -6323 # . reclaim locals -6324 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP -6325 # . restore registers -6326 5f/pop-to-EDI -6327 5e/pop-to-ESI -6328 5a/pop-to-EDX -6329 59/pop-to-ECX -6330 # . epilog -6331 89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . . # copy EBP to ESP -6332 5d/pop-to-EBP -6333 c3/return -6334 -6335 test-has-metadata-true: -6336 # . prolog -6337 55/push-EBP -6338 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP -6339 # (EAX..ECX) = "ab/c" -6340 b8/copy-to-EAX "ab/c"/imm32 -6341 8b/copy 0/mod/indirect 0/rm32/EAX . . . 1/r32/ECX . . # copy *EAX to ECX -6342 8d/copy-address 1/mod/*+disp8 4/rm32/sib 0/base/EAX 1/index/ECX . 1/r32/ECX 4/disp8 . # copy EAX+ECX+4 to ECX -6343 05/add-to-EAX 4/imm32 -6344 # var in/ESI : (address slice) = {EAX, ECX} -6345 51/push-ECX -6346 50/push-EAX -6347 89/copy 3/mod/direct 6/rm32/ESI . . . 4/r32/ESP . . # copy ESP to ESI -6348 # EAX = has-metadata?(ESI, "c") -6349 # . . push args -6350 68/push "c"/imm32 -6351 56/push-ESI -6352 # . . call -6353 e8/call has-metadata?/disp32 -6354 # . . discard args -6355 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP -6356 # check-ints-equal(EAX, 1, msg) -6357 # . . push args -6358 68/push "F - test-has-metadata-true"/imm32 -6359 68/push 1/imm32/true -6360 50/push-EAX -6361 # . . call -6362 e8/call check-ints-equal/disp32 -6363 # . . discard args -6364 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP -6365 # . epilog -6366 89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . . # copy EBP to ESP -6367 5d/pop-to-EBP -6368 c3/return -6369 -6370 test-has-metadata-false: -6371 # . prolog -6372 55/push-EBP -6373 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP -6374 # (EAX..ECX) = "ab/c" -6375 b8/copy-to-EAX "ab/c"/imm32 -6376 8b/copy 0/mod/indirect 0/rm32/EAX . . . 1/r32/ECX . . # copy *EAX to ECX -6377 8d/copy-address 1/mod/*+disp8 4/rm32/sib 0/base/EAX 1/index/ECX . 1/r32/ECX 4/disp8 . # copy EAX+ECX+4 to ECX -6378 05/add-to-EAX 4/imm32 -6379 # var in/ESI : (address slice) = {EAX, ECX} -6380 51/push-ECX -6381 50/push-EAX -6382 89/copy 3/mod/direct 6/rm32/ESI . . . 4/r32/ESP . . # copy ESP to ESI -6383 # EAX = has-metadata?(ESI, "c") -6384 # . . push args -6385 68/push "d"/imm32 -6386 56/push-ESI -6387 # . . call -6388 e8/call has-metadata?/disp32 -6389 # . . discard args -6390 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP -6391 # check-ints-equal(EAX, 0, msg) -6392 # . . push args -6393 68/push "F - test-has-metadata-false"/imm32 -6394 68/push 0/imm32/false -6395 50/push-EAX -6396 # . . call -6397 e8/call check-ints-equal/disp32 -6398 # . . discard args -6399 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP -6400 # . epilog -6401 89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . . # copy EBP to ESP -6402 5d/pop-to-EBP -6403 c3/return -6404 -6405 test-has-metadata-ignore-name: -6406 # . prolog -6407 55/push-EBP -6408 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP -6409 # (EAX..ECX) = "a/b" -6410 b8/copy-to-EAX "a/b"/imm32 -6411 8b/copy 0/mod/indirect 0/rm32/EAX . . . 1/r32/ECX . . # copy *EAX to ECX -6412 8d/copy-address 1/mod/*+disp8 4/rm32/sib 0/base/EAX 1/index/ECX . 1/r32/ECX 4/disp8 . # copy EAX+ECX+4 to ECX -6413 05/add-to-EAX 4/imm32 -6414 # var in/ESI : (address slice) = {EAX, ECX} -6415 51/push-ECX -6416 50/push-EAX -6417 89/copy 3/mod/direct 6/rm32/ESI . . . 4/r32/ESP . . # copy ESP to ESI -6418 # EAX = has-metadata?(ESI, "a") -6419 # . . push args -6420 68/push "a"/imm32 -6421 56/push-ESI -6422 # . . call -6423 e8/call has-metadata?/disp32 -6424 # . . discard args -6425 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP -6426 # check-ints-equal(EAX, 0, msg) -6427 # . . push args -6428 68/push "F - test-has-metadata-ignore-name"/imm32 -6429 68/push 0/imm32/false -6430 50/push-EAX -6431 # . . call -6432 e8/call check-ints-equal/disp32 -6433 # . . discard args -6434 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP +6298 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP +6299 # check-ints-equal(EAX, 1, msg) +6300 # . . push args +6301 68/push "F - test-has-metadata-multiple-true"/imm32 +6302 68/push 1/imm32/true +6303 50/push-EAX +6304 # . . call +6305 e8/call check-ints-equal/disp32 +6306 # . . discard args +6307 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP +6308 # . epilog +6309 89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . . # copy EBP to ESP +6310 5d/pop-to-EBP +6311 c3/return +6312 +6313 test-has-metadata-multiple-false: +6314 # . prolog +6315 55/push-EBP +6316 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP +6317 # (EAX..ECX) = "a/b/c" +6318 b8/copy-to-EAX "a/b/c"/imm32 +6319 8b/copy 0/mod/indirect 0/rm32/EAX . . . 1/r32/ECX . . # copy *EAX to ECX +6320 8d/copy-address 1/mod/*+disp8 4/rm32/sib 0/base/EAX 1/index/ECX . 1/r32/ECX 4/disp8 . # copy EAX+ECX+4 to ECX +6321 05/add-to-EAX 4/imm32 +6322 # var in/ESI : (address slice) = {EAX, ECX} +6323 51/push-ECX +6324 50/push-EAX +6325 89/copy 3/mod/direct 6/rm32/ESI . . . 4/r32/ESP . . # copy ESP to ESI +6326 # EAX = has-metadata?(ESI, "d") +6327 # . . push args +6328 68/push "d"/imm32 +6329 56/push-ESI +6330 # . . call +6331 e8/call has-metadata?/disp32 +6332 # . . discard args +6333 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP +6334 # check-ints-equal(EAX, 0, msg) +6335 # . . push args +6336 68/push "F - test-has-metadata-multiple-false"/imm32 +6337 68/push 0/imm32/false +6338 50/push-EAX +6339 # . . call +6340 e8/call check-ints-equal/disp32 +6341 # . . discard args +6342 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP +6343 # . epilog +6344 89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . . # copy EBP to ESP +6345 5d/pop-to-EBP +6346 c3/return +6347 +6348 # If datum of 'word' is not a valid name, it must be a hex int. Parse and print +6349 # it in 'width' bytes of hex, least significant first. +6350 # Otherwise just print the entire word including metadata. +6351 # Always print a trailing space. +6352 emit: # out : (address buffered-file), word : (address slice), width : int -> <void> +6353 # . prolog +6354 55/push-EBP +6355 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP +6356 # . save registers +6357 50/push-EAX +6358 56/push-ESI +6359 57/push-EDI +6360 # ESI = word +6361 8b/copy 1/mod/*+disp8 5/rm32/EBP . . . 6/r32/ESI 0xc/disp8 . # copy *(EBP+12) to ESI +6362 # var name/EDI : (address slice) = {0, 0} +6363 68/push 0/imm32/end +6364 68/push 0/imm32/start +6365 89/copy 3/mod/direct 7/rm32/EDI . . . 4/r32/ESP . . # copy ESP to EDI +6366 # datum = next-token-from-slice(word->start, word->end, '/') +6367 # . . push args +6368 57/push-EDI +6369 68/push 0x2f/imm32/slash +6370 ff 6/subop/push 1/mod/*+disp8 6/rm32/ESI . . . . 4/disp8 . # push *(ESI+4) +6371 ff 6/subop/push 0/mod/indirect 6/rm32/ESI . . . . . . # push *ESI +6372 # . . call +6373 e8/call next-token-from-slice/disp32 +6374 # . . discard args +6375 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0x10/imm32 # add to ESP +6376 # if (is-valid-name?(datum)) write-slice(out, word) and return +6377 # . EAX = is-valid-name?(name) +6378 # . . push args +6379 57/push-EDI +6380 # . . call +6381 e8/call is-valid-name?/disp32 +6382 # . . discard args +6383 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP +6384 # . if (EAX != 0) +6385 3d/compare-EAX-and 0/imm32 +6386 74/jump-if-equal $emit:hex-int/disp8 +6387 $emit:name: +6388 # . write-slice(out, word) +6389 # . . push args +6390 56/push-ESI +6391 ff 6/subop/push 1/mod/*+disp8 5/rm32/EBP . . . . 8/disp8 . # push *(EBP+8) +6392 # . . call +6393 e8/call write-slice/disp32 +6394 # . . discard args +6395 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP +6396 # . write-buffered(out, " ") +6397 # . . push args +6398 68/push " "/imm32 +6399 ff 6/subop/push 1/mod/*+disp8 5/rm32/EBP . . . . 8/disp8 . # push *(EBP+8) +6400 # . . call +6401 e8/call write-buffered/disp32 +6402 # . . discard args +6403 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP +6404 # . return +6405 eb/jump $emit:end/disp8 +6406 # otherwise emit-hex(out, parse-hex-int(datum), width) +6407 # (Weird shit can happen here if the datum of 'word' isn't either a valid +6408 # name or a hex number, but we're only going to be passing in real legal +6409 # programs. We just want to make sure that valid names aren't treated as +6410 # (valid) hex numbers.) +6411 $emit:hex-int: +6412 # . value/EAX = parse-hex-int(datum) +6413 # . . push args +6414 57/push-EDI +6415 # . . call +6416 e8/call parse-hex-int/disp32 +6417 # . . discard args +6418 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP +6419 # . emit-hex(out, value, width) +6420 # . . push args +6421 ff 6/subop/push 1/mod/*+disp8 5/rm32/EBP . . . . 0x10/disp8 . # push *(EBP+16) +6422 50/push-EAX +6423 ff 6/subop/push 1/mod/*+disp8 5/rm32/EBP . . . . 8/disp8 . # push *(EBP+8) +6424 # . . call +6425 e8/call emit-hex/disp32 +6426 # . . discard args +6427 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP +6428 $emit:end: +6429 # . reclaim locals +6430 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP +6431 # . restore registers +6432 5f/pop-to-EDI +6433 5e/pop-to-ESI +6434 58/pop-to-EAX 6435 # . epilog 6436 89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . . # copy EBP to ESP 6437 5d/pop-to-EBP 6438 c3/return 6439 -6440 test-has-metadata-multiple-true: +6440 test-emit-number: 6441 # . prolog 6442 55/push-EBP 6443 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP -6444 # (EAX..ECX) = "a/b/c" -6445 b8/copy-to-EAX "a/b/c"/imm32 -6446 8b/copy 0/mod/indirect 0/rm32/EAX . . . 1/r32/ECX . . # copy *EAX to ECX -6447 8d/copy-address 1/mod/*+disp8 4/rm32/sib 0/base/EAX 1/index/ECX . 1/r32/ECX 4/disp8 . # copy EAX+ECX+4 to ECX -6448 05/add-to-EAX 4/imm32 -6449 # var in/ESI : (address slice) = {EAX, ECX} -6450 51/push-ECX -6451 50/push-EAX -6452 89/copy 3/mod/direct 6/rm32/ESI . . . 4/r32/ESP . . # copy ESP to ESI -6453 # EAX = has-metadata?(ESI, "c") -6454 # . . push args -6455 68/push "c"/imm32 -6456 56/push-ESI +6444 # setup +6445 # . clear-stream(_test-output-stream) +6446 # . . push args +6447 68/push _test-output-stream/imm32 +6448 # . . call +6449 e8/call clear-stream/disp32 +6450 # . . discard args +6451 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP +6452 # . clear-stream(_test-output-buffered-file+4) +6453 # . . push args +6454 b8/copy-to-EAX _test-output-buffered-file/imm32 +6455 05/add-to-EAX 4/imm32 +6456 50/push-EAX 6457 # . . call -6458 e8/call has-metadata?/disp32 +6458 e8/call clear-stream/disp32 6459 # . . discard args -6460 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP -6461 # check-ints-equal(EAX, 1, msg) -6462 # . . push args -6463 68/push "F - test-has-metadata-multiple-true"/imm32 -6464 68/push 1/imm32/true -6465 50/push-EAX -6466 # . . call -6467 e8/call check-ints-equal/disp32 -6468 # . . discard args -6469 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP -6470 # . epilog -6471 89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . . # copy EBP to ESP -6472 5d/pop-to-EBP -6473 c3/return -6474 -6475 test-has-metadata-multiple-false: -6476 # . prolog -6477 55/push-EBP -6478 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP -6479 # (EAX..ECX) = "a/b/c" -6480 b8/copy-to-EAX "a/b/c"/imm32 -6481 8b/copy 0/mod/indirect 0/rm32/EAX . . . 1/r32/ECX . . # copy *EAX to ECX -6482 8d/copy-address 1/mod/*+disp8 4/rm32/sib 0/base/EAX 1/index/ECX . 1/r32/ECX 4/disp8 . # copy EAX+ECX+4 to ECX -6483 05/add-to-EAX 4/imm32 -6484 # var in/ESI : (address slice) = {EAX, ECX} -6485 51/push-ECX -6486 50/push-EAX -6487 89/copy 3/mod/direct 6/rm32/ESI . . . 4/r32/ESP . . # copy ESP to ESI -6488 # EAX = has-metadata?(ESI, "d") -6489 # . . push args -6490 68/push "d"/imm32 -6491 56/push-ESI -6492 # . . call -6493 e8/call has-metadata?/disp32 -6494 # . . discard args -6495 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP -6496 # check-ints-equal(EAX, 0, msg) -6497 # . . push args -6498 68/push "F - test-has-metadata-multiple-false"/imm32 -6499 68/push 0/imm32/false -6500 50/push-EAX -6501 # . . call -6502 e8/call check-ints-equal/disp32 -6503 # . . discard args -6504 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP -6505 # . epilog -6506 89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . . # copy EBP to ESP -6507 5d/pop-to-EBP -6508 c3/return -6509 -6510 # If datum of 'word' is not a valid name, it must be a hex int. Parse and print -6511 # it in 'width' bytes of hex, least significant first. -6512 # Otherwise just print the entire word including metadata. -6513 # Always print a trailing space. -6514 emit: # out : (address buffered-file), word : (address slice), width : int -> <void> -6515 # . prolog -6516 55/push-EBP -6517 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP -6518 # . save registers -6519 50/push-EAX -6520 56/push-ESI -6521 57/push-EDI -6522 # ESI = word -6523 8b/copy 1/mod/*+disp8 5/rm32/EBP . . . 6/r32/ESI 0xc/disp8 . # copy *(EBP+12) to ESI -6524 # var name/EDI : (address slice) = {0, 0} -6525 68/push 0/imm32/end -6526 68/push 0/imm32/start -6527 89/copy 3/mod/direct 7/rm32/EDI . . . 4/r32/ESP . . # copy ESP to EDI -6528 # datum = next-token-from-slice(word->start, word->end, '/') -6529 # . . push args -6530 57/push-EDI -6531 68/push 0x2f/imm32/slash -6532 ff 6/subop/push 1/mod/*+disp8 6/rm32/ESI . . . . 4/disp8 . # push *(ESI+4) -6533 ff 6/subop/push 0/mod/indirect 6/rm32/ESI . . . . . . # push *ESI -6534 # . . call -6535 e8/call next-token-from-slice/disp32 -6536 # . . discard args -6537 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0x10/imm32 # add to ESP -6538 # if (is-valid-name?(datum)) write-slice(out, word) and return -6539 # . EAX = is-valid-name?(name) -6540 # . . push args -6541 57/push-EDI +6460 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP +6461 # var slice/ECX = "30" +6462 68/push _test-slice-three-zero-end/imm32/end +6463 68/push _test-slice-three-zero/imm32/start +6464 89/copy 3/mod/direct 1/rm32/ECX . . . 4/r32/ESP . . # copy ESP to ECX +6465 # emit(_test-output-buffered-file, slice, 1) +6466 # . . push args +6467 68/push 1/imm32 +6468 51/push-ECX +6469 68/push _test-output-buffered-file/imm32 +6470 # . . call +6471 e8/call emit/disp32 +6472 # . . discard args +6473 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP +6474 # flush(_test-output-buffered-file) +6475 # . . push args +6476 68/push _test-output-buffered-file/imm32 +6477 # . . call +6478 e8/call flush/disp32 +6479 # . . discard args +6480 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP +6481 # check-stream-equal(_test-output-stream, "30 ", msg) +6482 # . . push args +6483 68/push "F - test-emit-number/1"/imm32 +6484 68/push "30 "/imm32 +6485 68/push _test-output-stream/imm32 +6486 # . . call +6487 e8/call check-stream-equal/disp32 +6488 # . . discard args +6489 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP +6490 # . epilog +6491 89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . . # copy EBP to ESP +6492 5d/pop-to-EBP +6493 c3/return +6494 +6495 test-emit-negative-number: +6496 # test support for sign-extending negative numbers +6497 # . prolog +6498 55/push-EBP +6499 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP +6500 # setup +6501 # . clear-stream(_test-output-stream) +6502 # . . push args +6503 68/push _test-output-stream/imm32 +6504 # . . call +6505 e8/call clear-stream/disp32 +6506 # . . discard args +6507 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP +6508 # . clear-stream(_test-output-buffered-file+4) +6509 # . . push args +6510 b8/copy-to-EAX _test-output-buffered-file/imm32 +6511 05/add-to-EAX 4/imm32 +6512 50/push-EAX +6513 # . . call +6514 e8/call clear-stream/disp32 +6515 # . . discard args +6516 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP +6517 # var slice/ECX = "-2" +6518 68/push _test-slice-negative-two-end/imm32/end +6519 68/push _test-slice-negative-two/imm32/start +6520 89/copy 3/mod/direct 1/rm32/ECX . . . 4/r32/ESP . . # copy ESP to ECX +6521 # emit(_test-output-buffered-file, slice, 2) +6522 # . . push args +6523 68/push 2/imm32 +6524 51/push-ECX +6525 68/push _test-output-buffered-file/imm32 +6526 # . . call +6527 e8/call emit/disp32 +6528 # . . discard args +6529 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP +6530 # flush(_test-output-buffered-file) +6531 # . . push args +6532 68/push _test-output-buffered-file/imm32 +6533 # . . call +6534 e8/call flush/disp32 +6535 # . . discard args +6536 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP +6537 # check-stream-equal(_test-output-stream, "fe ff ", msg) +6538 # . . push args +6539 68/push "F - test-emit-number/1"/imm32 +6540 68/push "fe ff "/imm32 +6541 68/push _test-output-stream/imm32 6542 # . . call -6543 e8/call is-valid-name?/disp32 +6543 e8/call check-stream-equal/disp32 6544 # . . discard args -6545 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP -6546 # . if (EAX != 0) -6547 3d/compare-EAX-and 0/imm32 -6548 74/jump-if-equal $emit:hex-int/disp8 -6549 $emit:name: -6550 # . write-slice(out, word) -6551 # . . push args -6552 56/push-ESI -6553 ff 6/subop/push 1/mod/*+disp8 5/rm32/EBP . . . . 8/disp8 . # push *(EBP+8) -6554 # . . call -6555 e8/call write-slice/disp32 -6556 # . . discard args -6557 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP -6558 # . write-buffered(out, " ") -6559 # . . push args -6560 68/push " "/imm32 -6561 ff 6/subop/push 1/mod/*+disp8 5/rm32/EBP . . . . 8/disp8 . # push *(EBP+8) -6562 # . . call -6563 e8/call write-buffered/disp32 -6564 # . . discard args -6565 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP -6566 # . return -6567 eb/jump $emit:end/disp8 -6568 # otherwise emit-hex(out, parse-hex-int(datum), width) -6569 # (Weird shit can happen here if the datum of 'word' isn't either a valid -6570 # name or a hex number, but we're only going to be passing in real legal -6571 # programs. We just want to make sure that valid names aren't treated as -6572 # (valid) hex numbers.) -6573 $emit:hex-int: -6574 # . value/EAX = parse-hex-int(datum) -6575 # . . push args -6576 57/push-EDI -6577 # . . call -6578 e8/call parse-hex-int/disp32 -6579 # . . discard args -6580 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP -6581 # . emit-hex(out, value, width) -6582 # . . push args -6583 ff 6/subop/push 1/mod/*+disp8 5/rm32/EBP . . . . 0x10/disp8 . # push *(EBP+16) -6584 50/push-EAX -6585 ff 6/subop/push 1/mod/*+disp8 5/rm32/EBP . . . . 8/disp8 . # push *(EBP+8) -6586 # . . call -6587 e8/call emit-hex/disp32 -6588 # . . discard args -6589 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP -6590 $emit:end: -6591 # . reclaim locals -6592 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP -6593 # . restore registers -6594 5f/pop-to-EDI -6595 5e/pop-to-ESI -6596 58/pop-to-EAX -6597 # . epilog -6598 89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . . # copy EBP to ESP -6599 5d/pop-to-EBP -6600 c3/return -6601 -6602 test-emit-number: -6603 # . prolog -6604 55/push-EBP -6605 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP -6606 # setup -6607 # . clear-stream(_test-output-stream) -6608 # . . push args -6609 68/push _test-output-stream/imm32 -6610 # . . call -6611 e8/call clear-stream/disp32 -6612 # . . discard args -6613 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP -6614 # . clear-stream(_test-output-buffered-file+4) -6615 # . . push args -6616 b8/copy-to-EAX _test-output-buffered-file/imm32 -6617 05/add-to-EAX 4/imm32 -6618 50/push-EAX -6619 # . . call -6620 e8/call clear-stream/disp32 -6621 # . . discard args -6622 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP -6623 # var slice/ECX = "30" -6624 68/push _test-slice-three-zero-end/imm32/end -6625 68/push _test-slice-three-zero/imm32/start -6626 89/copy 3/mod/direct 1/rm32/ECX . . . 4/r32/ESP . . # copy ESP to ECX -6627 # emit(_test-output-buffered-file, slice, 1) -6628 # . . push args -6629 68/push 1/imm32 -6630 51/push-ECX -6631 68/push _test-output-buffered-file/imm32 -6632 # . . call -6633 e8/call emit/disp32 -6634 # . . discard args -6635 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP -6636 # flush(_test-output-buffered-file) -6637 # . . push args -6638 68/push _test-output-buffered-file/imm32 -6639 # . . call -6640 e8/call flush/disp32 -6641 # . . discard args -6642 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP -6643 # check-stream-equal(_test-output-stream, "30 ", msg) -6644 # . . push args -6645 68/push "F - test-emit-number/1"/imm32 -6646 68/push "30 "/imm32 -6647 68/push _test-output-stream/imm32 -6648 # . . call -6649 e8/call check-stream-equal/disp32 -6650 # . . discard args -6651 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP -6652 # . epilog -6653 89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . . # copy EBP to ESP -6654 5d/pop-to-EBP -6655 c3/return -6656 -6657 test-emit-negative-number: -6658 # test support for sign-extending negative numbers -6659 # . prolog -6660 55/push-EBP -6661 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP -6662 # setup -6663 # . clear-stream(_test-output-stream) -6664 # . . push args -6665 68/push _test-output-stream/imm32 -6666 # . . call -6667 e8/call clear-stream/disp32 -6668 # . . discard args -6669 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP -6670 # . clear-stream(_test-output-buffered-file+4) -6671 # . . push args -6672 b8/copy-to-EAX _test-output-buffered-file/imm32 -6673 05/add-to-EAX 4/imm32 -6674 50/push-EAX -6675 # . . call -6676 e8/call clear-stream/disp32 -6677 # . . discard args -6678 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP -6679 # var slice/ECX = "-2" -6680 68/push _test-slice-negative-two-end/imm32/end -6681 68/push _test-slice-negative-two/imm32/start -6682 89/copy 3/mod/direct 1/rm32/ECX . . . 4/r32/ESP . . # copy ESP to ECX -6683 # emit(_test-output-buffered-file, slice, 2) -6684 # . . push args -6685 68/push 2/imm32 -6686 51/push-ECX -6687 68/push _test-output-buffered-file/imm32 -6688 # . . call -6689 e8/call emit/disp32 -6690 # . . discard args -6691 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP -6692 # flush(_test-output-buffered-file) -6693 # . . push args -6694 68/push _test-output-buffered-file/imm32 -6695 # . . call -6696 e8/call flush/disp32 -6697 # . . discard args -6698 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP -6699 # check-stream-equal(_test-output-stream, "fe ff ", msg) -6700 # . . push args -6701 68/push "F - test-emit-number/1"/imm32 -6702 68/push "fe ff "/imm32 -6703 68/push _test-output-stream/imm32 -6704 # . . call -6705 e8/call check-stream-equal/disp32 -6706 # . . discard args -6707 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP -6708 # . epilog -6709 89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . . # copy EBP to ESP -6710 5d/pop-to-EBP -6711 c3/return -6712 -6713 test-emit-number-with-metadata: -6714 # . prolog -6715 55/push-EBP -6716 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP -6717 # setup -6718 # . clear-stream(_test-output-stream) -6719 # . . push args -6720 68/push _test-output-stream/imm32 -6721 # . . call -6722 e8/call clear-stream/disp32 -6723 # . . discard args -6724 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP -6725 # . clear-stream(_test-output-buffered-file+4) -6726 # . . push args -6727 b8/copy-to-EAX _test-output-buffered-file/imm32 -6728 05/add-to-EAX 4/imm32 -6729 50/push-EAX -6730 # . . call -6731 e8/call clear-stream/disp32 -6732 # . . discard args -6733 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP -6734 # var slice/ECX = "-2/foo" -6735 68/push _test-slice-negative-two-metadata-end/imm32/end -6736 68/push _test-slice-negative-two/imm32/start -6737 89/copy 3/mod/direct 1/rm32/ECX . . . 4/r32/ESP . . # copy ESP to ECX -6738 # emit(_test-output-buffered-file, slice, 2) -6739 # . . push args -6740 68/push 2/imm32 -6741 51/push-ECX -6742 68/push _test-output-buffered-file/imm32 -6743 # . . call -6744 e8/call emit/disp32 -6745 # . . discard args -6746 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP -6747 # flush(_test-output-buffered-file) -6748 # . . push args -6749 68/push _test-output-buffered-file/imm32 -6750 # . . call -6751 e8/call flush/disp32 -6752 # . . discard args -6753 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP -6754 # the '/foo' will have no impact on the output -6755 # check-stream-equal(_test-output-stream, "fe ff ", msg) -6756 # . . push args -6757 68/push "F - test-emit-number-with-metadata"/imm32 -6758 68/push "fe ff "/imm32 -6759 68/push _test-output-stream/imm32 -6760 # . . call -6761 e8/call check-stream-equal/disp32 -6762 # . . discard args -6763 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP -6764 # . epilog -6765 89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . . # copy EBP to ESP -6766 5d/pop-to-EBP -6767 c3/return -6768 -6769 test-emit-non-number: -6770 # . prolog -6771 55/push-EBP -6772 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP -6773 # setup -6774 # . clear-stream(_test-output-stream) -6775 # . . push args -6776 68/push _test-output-stream/imm32 -6777 # . . call -6778 e8/call clear-stream/disp32 -6779 # . . discard args -6780 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP -6781 # . clear-stream(_test-output-buffered-file+4) -6782 # . . push args -6783 b8/copy-to-EAX _test-output-buffered-file/imm32 -6784 05/add-to-EAX 4/imm32 -6785 50/push-EAX -6786 # . . call -6787 e8/call clear-stream/disp32 -6788 # . . discard args -6789 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP -6790 # var slice/ECX = "xyz" -6791 68/push _test-slice-non-number-word-end/imm32/end -6792 68/push _test-slice-non-number-word/imm32/start -6793 89/copy 3/mod/direct 1/rm32/ECX . . . 4/r32/ESP . . # copy ESP to ECX -6794 # emit(_test-output-buffered-file, slice, 2) -6795 # . . push args -6796 68/push 2/imm32 -6797 51/push-ECX -6798 68/push _test-output-buffered-file/imm32 -6799 # . . call -6800 e8/call emit/disp32 -6801 # . . discard args -6802 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP -6803 # flush(_test-output-buffered-file) -6804 # . . push args -6805 68/push _test-output-buffered-file/imm32 -6806 # . . call -6807 e8/call flush/disp32 -6808 # . . discard args -6809 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP -6810 # check-stream-equal(_test-output-stream, "xyz", msg) -6811 # . . push args -6812 68/push "F - test-emit-non-number"/imm32 -6813 68/push "xyz "/imm32 -6814 68/push _test-output-stream/imm32 -6815 # . . call -6816 e8/call check-stream-equal/disp32 -6817 # . . discard args -6818 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP -6819 # . epilog -6820 89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . . # copy EBP to ESP -6821 5d/pop-to-EBP -6822 c3/return -6823 -6824 test-emit-non-number-with-metadata: -6825 # . prolog -6826 55/push-EBP -6827 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP -6828 # setup -6829 # . clear-stream(_test-output-stream) -6830 # . . push args -6831 68/push _test-output-stream/imm32 -6832 # . . call -6833 e8/call clear-stream/disp32 -6834 # . . discard args -6835 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP -6836 # . clear-stream(_test-output-buffered-file+4) -6837 # . . push args -6838 b8/copy-to-EAX _test-output-buffered-file/imm32 -6839 05/add-to-EAX 4/imm32 -6840 50/push-EAX -6841 # . . call -6842 e8/call clear-stream/disp32 -6843 # . . discard args -6844 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP -6845 # var slice/ECX = "xyz/" -6846 68/push _test-slice-non-number-word-metadata-end/imm32/end -6847 68/push _test-slice-non-number-word/imm32/start -6848 89/copy 3/mod/direct 1/rm32/ECX . . . 4/r32/ESP . . # copy ESP to ECX -6849 # emit(_test-output-buffered-file, slice, 2) -6850 # . . push args -6851 68/push 2/imm32 -6852 51/push-ECX -6853 68/push _test-output-buffered-file/imm32 -6854 # . . call -6855 e8/call emit/disp32 -6856 # . . discard args -6857 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP -6858 # flush(_test-output-buffered-file) -6859 # . . push args -6860 68/push _test-output-buffered-file/imm32 -6861 # . . call -6862 e8/call flush/disp32 -6863 # . . discard args -6864 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP -6865 # check-stream-equal(_test-output-stream, "xyz/", msg) -6866 # . . push args -6867 68/push "F - test-emit-non-number-with-metadata"/imm32 -6868 68/push "xyz/ "/imm32 -6869 68/push _test-output-stream/imm32 -6870 # . . call -6871 e8/call check-stream-equal/disp32 -6872 # . . discard args -6873 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP -6874 # . epilog -6875 89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . . # copy EBP to ESP -6876 5d/pop-to-EBP -6877 c3/return -6878 -6879 test-emit-non-number-with-all-hex-digits-and-metadata: -6880 # . prolog -6881 55/push-EBP -6882 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP -6883 # setup -6884 # . clear-stream(_test-output-stream) -6885 # . . push args -6886 68/push _test-output-stream/imm32 -6887 # . . call -6888 e8/call clear-stream/disp32 -6889 # . . discard args -6890 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP -6891 # . clear-stream(_test-output-buffered-file+4) -6892 # . . push args -6893 b8/copy-to-EAX _test-output-buffered-file/imm32 -6894 05/add-to-EAX 4/imm32 -6895 50/push-EAX -6896 # . . call -6897 e8/call clear-stream/disp32 -6898 # . . discard args -6899 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP -6900 # var slice/ECX = "abcd/xyz" -6901 68/push _test-slice-hexlike-non-number-word-metadata-end/imm32/end -6902 68/push _test-slice-hexlike-non-number-word/imm32/start -6903 89/copy 3/mod/direct 1/rm32/ECX . . . 4/r32/ESP . . # copy ESP to ECX -6904 # emit(_test-output-buffered-file, slice, 2) +6545 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP +6546 # . epilog +6547 89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . . # copy EBP to ESP +6548 5d/pop-to-EBP +6549 c3/return +6550 +6551 test-emit-number-with-metadata: +6552 # . prolog +6553 55/push-EBP +6554 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP +6555 # setup +6556 # . clear-stream(_test-output-stream) +6557 # . . push args +6558 68/push _test-output-stream/imm32 +6559 # . . call +6560 e8/call clear-stream/disp32 +6561 # . . discard args +6562 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP +6563 # . clear-stream(_test-output-buffered-file+4) +6564 # . . push args +6565 b8/copy-to-EAX _test-output-buffered-file/imm32 +6566 05/add-to-EAX 4/imm32 +6567 50/push-EAX +6568 # . . call +6569 e8/call clear-stream/disp32 +6570 # . . discard args +6571 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP +6572 # var slice/ECX = "-2/foo" +6573 68/push _test-slice-negative-two-metadata-end/imm32/end +6574 68/push _test-slice-negative-two/imm32/start +6575 89/copy 3/mod/direct 1/rm32/ECX . . . 4/r32/ESP . . # copy ESP to ECX +6576 # emit(_test-output-buffered-file, slice, 2) +6577 # . . push args +6578 68/push 2/imm32 +6579 51/push-ECX +6580 68/push _test-output-buffered-file/imm32 +6581 # . . call +6582 e8/call emit/disp32 +6583 # . . discard args +6584 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP +6585 # flush(_test-output-buffered-file) +6586 # . . push args +6587 68/push _test-output-buffered-file/imm32 +6588 # . . call +6589 e8/call flush/disp32 +6590 # . . discard args +6591 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP +6592 # the '/foo' will have no impact on the output +6593 # check-stream-equal(_test-output-stream, "fe ff ", msg) +6594 # . . push args +6595 68/push "F - test-emit-number-with-metadata"/imm32 +6596 68/push "fe ff "/imm32 +6597 68/push _test-output-stream/imm32 +6598 # . . call +6599 e8/call check-stream-equal/disp32 +6600 # . . discard args +6601 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP +6602 # . epilog +6603 89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . . # copy EBP to ESP +6604 5d/pop-to-EBP +6605 c3/return +6606 +6607 test-emit-non-number: +6608 # . prolog +6609 55/push-EBP +6610 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP +6611 # setup +6612 # . clear-stream(_test-output-stream) +6613 # . . push args +6614 68/push _test-output-stream/imm32 +6615 # . . call +6616 e8/call clear-stream/disp32 +6617 # . . discard args +6618 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP +6619 # . clear-stream(_test-output-buffered-file+4) +6620 # . . push args +6621 b8/copy-to-EAX _test-output-buffered-file/imm32 +6622 05/add-to-EAX 4/imm32 +6623 50/push-EAX +6624 # . . call +6625 e8/call clear-stream/disp32 +6626 # . . discard args +6627 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP +6628 # var slice/ECX = "xyz" +6629 68/push _test-slice-non-number-word-end/imm32/end +6630 68/push _test-slice-non-number-word/imm32/start +6631 89/copy 3/mod/direct 1/rm32/ECX . . . 4/r32/ESP . . # copy ESP to ECX +6632 # emit(_test-output-buffered-file, slice, 2) +6633 # . . push args +6634 68/push 2/imm32 +6635 51/push-ECX +6636 68/push _test-output-buffered-file/imm32 +6637 # . . call +6638 e8/call emit/disp32 +6639 # . . discard args +6640 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP +6641 # flush(_test-output-buffered-file) +6642 # . . push args +6643 68/push _test-output-buffered-file/imm32 +6644 # . . call +6645 e8/call flush/disp32 +6646 # . . discard args +6647 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP +6648 # check-stream-equal(_test-output-stream, "xyz", msg) +6649 # . . push args +6650 68/push "F - test-emit-non-number"/imm32 +6651 68/push "xyz "/imm32 +6652 68/push _test-output-stream/imm32 +6653 # . . call +6654 e8/call check-stream-equal/disp32 +6655 # . . discard args +6656 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP +6657 # . epilog +6658 89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . . # copy EBP to ESP +6659 5d/pop-to-EBP +6660 c3/return +6661 +6662 test-emit-non-number-with-metadata: +6663 # . prolog +6664 55/push-EBP +6665 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP +6666 # setup +6667 # . clear-stream(_test-output-stream) +6668 # . . push args +6669 68/push _test-output-stream/imm32 +6670 # . . call +6671 e8/call clear-stream/disp32 +6672 # . . discard args +6673 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP +6674 # . clear-stream(_test-output-buffered-file+4) +6675 # . . push args +6676 b8/copy-to-EAX _test-output-buffered-file/imm32 +6677 05/add-to-EAX 4/imm32 +6678 50/push-EAX +6679 # . . call +6680 e8/call clear-stream/disp32 +6681 # . . discard args +6682 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP +6683 # var slice/ECX = "xyz/" +6684 68/push _test-slice-non-number-word-metadata-end/imm32/end +6685 68/push _test-slice-non-number-word/imm32/start +6686 89/copy 3/mod/direct 1/rm32/ECX . . . 4/r32/ESP . . # copy ESP to ECX +6687 # emit(_test-output-buffered-file, slice, 2) +6688 # . . push args +6689 68/push 2/imm32 +6690 51/push-ECX +6691 68/push _test-output-buffered-file/imm32 +6692 # . . call +6693 e8/call emit/disp32 +6694 # . . discard args +6695 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP +6696 # flush(_test-output-buffered-file) +6697 # . . push args +6698 68/push _test-output-buffered-file/imm32 +6699 # . . call +6700 e8/call flush/disp32 +6701 # . . discard args +6702 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP +6703 # check-stream-equal(_test-output-stream, "xyz/", msg) +6704 # . . push args +6705 68/push "F - test-emit-non-number-with-metadata"/imm32 +6706 68/push "xyz/ "/imm32 +6707 68/push _test-output-stream/imm32 +6708 # . . call +6709 e8/call check-stream-equal/disp32 +6710 # . . discard args +6711 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP +6712 # . epilog +6713 89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . . # copy EBP to ESP +6714 5d/pop-to-EBP +6715 c3/return +6716 +6717 test-emit-non-number-with-all-hex-digits-and-metadata: +6718 # . prolog +6719 55/push-EBP +6720 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP +6721 # setup +6722 # . clear-stream(_test-output-stream) +6723 # . . push args +6724 68/push _test-output-stream/imm32 +6725 # . . call +6726 e8/call clear-stream/disp32 +6727 # . . discard args +6728 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP +6729 # . clear-stream(_test-output-buffered-file+4) +6730 # . . push args +6731 b8/copy-to-EAX _test-output-buffered-file/imm32 +6732 05/add-to-EAX 4/imm32 +6733 50/push-EAX +6734 # . . call +6735 e8/call clear-stream/disp32 +6736 # . . discard args +6737 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP +6738 # var slice/ECX = "abcd/xyz" +6739 68/push _test-slice-hexlike-non-number-word-metadata-end/imm32/end +6740 68/push _test-slice-hexlike-non-number-word/imm32/start +6741 89/copy 3/mod/direct 1/rm32/ECX . . . 4/r32/ESP . . # copy ESP to ECX +6742 # emit(_test-output-buffered-file, slice, 2) +6743 # . . push args +6744 68/push 2/imm32 +6745 51/push-ECX +6746 68/push _test-output-buffered-file/imm32 +6747 # . . call +6748 e8/call emit/disp32 +6749 # . . discard args +6750 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP +6751 # flush(_test-output-buffered-file) +6752 # . . push args +6753 68/push _test-output-buffered-file/imm32 +6754 # . . call +6755 e8/call flush/disp32 +6756 # . . discard args +6757 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP +6758 +-- 26 lines: #? # dump output --------------------------------------------------------------------------------------------------------------------------- +6784 # check-stream-equal(_test-output-stream, "abcd/xyz") +6785 # . . push args +6786 68/push "F - test-emit-non-number-with-all-hex-digits"/imm32 +6787 68/push "abcd/xyz "/imm32 +6788 68/push _test-output-stream/imm32 +6789 # . . call +6790 e8/call check-stream-equal/disp32 +6791 # . . discard args +6792 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP +6793 # . epilog +6794 89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . . # copy EBP to ESP +6795 5d/pop-to-EBP +6796 c3/return +6797 +6798 # conditions for 'valid' names that are not at risk of looking like hex numbers +6799 # keep in sync with the rules in labels.cc +6800 #: - if it starts with a digit, it's treated as a number. If it can't be +6801 #: parsed as hex it will raise an error. +6802 #: - if it starts with '-' it's treated as a number. +6803 #: - if it starts with '0x' it's treated as a number. (redundant) +6804 #: - if it's two characters long, it can't be a name. Either it's a hex +6805 #: byte, or it raises an error. +6806 is-valid-name?: # in : (address slice) -> EAX : boolean +6807 # . prolog +6808 55/push-EBP +6809 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP +6810 # . save registers +6811 51/push-ECX +6812 56/push-ESI +6813 # ESI = in +6814 8b/copy 1/mod/*+disp8 5/rm32/EBP . . . 6/r32/ESI 8/disp8 . # copy *(EBP+8) to ESI +6815 # start/ECX = in->start +6816 8b/copy 0/mod/indirect 6/rm32/ESI . . . 1/r32/ECX . . # copy *ESI to ECX +6817 # end/EAX = in->end +6818 8b/copy 1/mod/*+disp8 6/rm32/ESI . . . 0/r32/EAX 4/disp8 . # copy *(ESI+4) to EAX +6819 $is-valid-name?:check0: +6820 # if (start >= end) return false +6821 39/compare 3/mod/direct 1/rm32/ECX . . . 0/r32/EAX . . # compare ECX with EAX +6822 7d/jump-if-greater-or-equal $is-valid-name?:false/disp8 +6823 $is-valid-name?:check1: +6824 # EAX -= ECX +6825 29/subtract 3/mod/direct 0/rm32/EAX . . . 1/r32/ECX . . # subtract ECX from EAX +6826 # if (EAX == 2) return false +6827 3d/compare-EAX-and 2/imm32 +6828 74/jump-if-equal $is-valid-name?:false/disp8 +6829 $is-valid-name?:check2: +6830 # c/EAX = *ECX +6831 31/xor 3/mod/direct 0/rm32/EAX . . . 0/r32/EAX . . # clear EAX +6832 8a/copy-byte 0/mod/indirect 1/rm32/ECX . . . 0/r32/AL . . # copy byte at *ECX to AL +6833 # if (c == "-") return false +6834 3d/compare-EAX-and 2d/imm32/- +6835 74/jump-if-equal $is-valid-name?:false/disp8 +6836 $is-valid-name?:check3a: +6837 # if (c < "0") return true +6838 3d/compare-EAX-with 30/imm32/0 +6839 7c/jump-if-lesser $is-valid-name?:true/disp8 +6840 $is-valid-name?:check3b: +6841 # if (c > "9") return true +6842 3d/compare-EAX-with 39/imm32/9 +6843 7f/jump-if-greater $is-valid-name?:true/disp8 +6844 $is-valid-name?:false: +6845 # return false +6846 b8/copy-to-EAX 0/imm32/false +6847 eb/jump $is-valid-name?:end/disp8 +6848 $is-valid-name?:true: +6849 # return true +6850 b8/copy-to-EAX 1/imm32/true +6851 $is-valid-name?:end: +6852 # . restore registers +6853 5e/pop-to-ESI +6854 59/pop-to-ECX +6855 # . epilog +6856 89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . . # copy EBP to ESP +6857 5d/pop-to-EBP +6858 c3/return +6859 +6860 test-is-valid-name-digit-prefix: +6861 # . prolog +6862 55/push-EBP +6863 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP +6864 # var slice/ECX = "34" +6865 68/push _test-slice-hex-int-end/imm32 +6866 68/push _test-slice-hex-int/imm32 +6867 89/copy 3/mod/direct 1/rm32/ECX . . . 4/r32/ESP . . # copy ESP to ECX +6868 # EAX = is-valid-name?(slice) +6869 # . . push args +6870 51/push-ECX +6871 # . . call +6872 e8/call is-valid-name?/disp32 +6873 # . . discard args +6874 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP +6875 # check-ints-equal(EAX, 0, msg) +6876 # . . push args +6877 68/push "F - test-is-valid-name-digit-prefix"/imm32 +6878 68/push 0/imm32/false +6879 50/push-EAX +6880 # . . call +6881 e8/call check-ints-equal/disp32 +6882 # . . discard args +6883 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP +6884 # . epilog +6885 89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . . # copy EBP to ESP +6886 5d/pop-to-EBP +6887 c3/return +6888 +6889 test-is-valid-name-negative-prefix: +6890 # . prolog +6891 55/push-EBP +6892 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP +6893 # var slice/ECX = "-0x34" +6894 68/push _test-slice-hex-int-with-0x-prefix-end/imm32 +6895 68/push _test-slice-hex-int-with-0x-prefix-negative/imm32 +6896 89/copy 3/mod/direct 1/rm32/ECX . . . 4/r32/ESP . . # copy ESP to ECX +6897 # EAX = is-valid-name?(slice) +6898 # . . push args +6899 51/push-ECX +6900 # . . call +6901 e8/call is-valid-name?/disp32 +6902 # . . discard args +6903 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP +6904 # check-ints-equal(EAX, 0, msg) 6905 # . . push args -6906 68/push 2/imm32 -6907 51/push-ECX -6908 68/push _test-output-buffered-file/imm32 +6906 68/push "F - test-is-valid-name-negative-prefix"/imm32 +6907 68/push 0/imm32/false +6908 50/push-EAX 6909 # . . call -6910 e8/call emit/disp32 +6910 e8/call check-ints-equal/disp32 6911 # . . discard args 6912 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP -6913 # flush(_test-output-buffered-file) -6914 # . . push args -6915 68/push _test-output-buffered-file/imm32 -6916 # . . call -6917 e8/call flush/disp32 -6918 # . . discard args -6919 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP -6920 +-- 34 lines: #? # dump output --------------------------------------------------------------------------------------------------------------------------- -6954 # check-stream-equal(_test-output-stream, "abcd/xyz") -6955 # . . push args -6956 68/push "F - test-emit-non-number-with-all-hex-digits"/imm32 -6957 68/push "abcd/xyz "/imm32 -6958 68/push _test-output-stream/imm32 -6959 # . . call -6960 e8/call check-stream-equal/disp32 -6961 # . . discard args -6962 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP -6963 # . epilog -6964 89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . . # copy EBP to ESP -6965 5d/pop-to-EBP -6966 c3/return -6967 -6968 # conditions for 'valid' names that are not at risk of looking like hex numbers -6969 # keep in sync with the rules in labels.cc -6970 #: - if it starts with a digit, it's treated as a number. If it can't be -6971 #: parsed as hex it will raise an error. -6972 #: - if it starts with '-' it's treated as a number. -6973 #: - if it starts with '0x' it's treated as a number. (redundant) -6974 #: - if it's two characters long, it can't be a name. Either it's a hex -6975 #: byte, or it raises an error. -6976 is-valid-name?: # in : (address slice) -> EAX : boolean +6913 # . epilog +6914 89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . . # copy EBP to ESP +6915 5d/pop-to-EBP +6916 c3/return +6917 +6918 test-is-valid-name-0x-prefix: +6919 # . prolog +6920 55/push-EBP +6921 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP +6922 # var slice/ECX = "0x34" +6923 68/push _test-slice-hex-int-with-0x-prefix-end/imm32 +6924 68/push _test-slice-hex-int-with-0x-prefix/imm32 +6925 89/copy 3/mod/direct 1/rm32/ECX . . . 4/r32/ESP . . # copy ESP to ECX +6926 # EAX = is-valid-name?(slice) +6927 # . . push args +6928 51/push-ECX +6929 # . . call +6930 e8/call is-valid-name?/disp32 +6931 # . . discard args +6932 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP +6933 # check-ints-equal(EAX, 0, msg) +6934 # . . push args +6935 68/push "F - test-is-valid-name-0x-prefix"/imm32 +6936 68/push 0/imm32/false +6937 50/push-EAX +6938 # . . call +6939 e8/call check-ints-equal/disp32 +6940 # . . discard args +6941 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP +6942 # . epilog +6943 89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . . # copy EBP to ESP +6944 5d/pop-to-EBP +6945 c3/return +6946 +6947 test-is-valid-name-starts-with-pre-digit: +6948 # . prolog +6949 55/push-EBP +6950 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP +6951 # var slice/ECX = "/03" +6952 68/push _test-slice-with-slash-prefix-end/imm32 +6953 68/push _test-slice-with-slash-prefix/imm32 +6954 89/copy 3/mod/direct 1/rm32/ECX . . . 4/r32/ESP . . # copy ESP to ECX +6955 # EAX = is-valid-name?(slice) +6956 # . . push args +6957 51/push-ECX +6958 # . . call +6959 e8/call is-valid-name?/disp32 +6960 # . . discard args +6961 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP +6962 # check-ints-equal(EAX, 1, msg) +6963 # . . push args +6964 68/push "F - test-is-valid-name-starts-with-pre-digit"/imm32 +6965 68/push 1/imm32/true +6966 50/push-EAX +6967 # . . call +6968 e8/call check-ints-equal/disp32 +6969 # . . discard args +6970 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP +6971 # . epilog +6972 89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . . # copy EBP to ESP +6973 5d/pop-to-EBP +6974 c3/return +6975 +6976 test-is-valid-name-starts-with-post-digit: 6977 # . prolog 6978 55/push-EBP 6979 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP -6980 # . save registers -6981 51/push-ECX -6982 56/push-ESI -6983 # ESI = in -6984 8b/copy 1/mod/*+disp8 5/rm32/EBP . . . 6/r32/ESI 8/disp8 . # copy *(EBP+8) to ESI -6985 # start/ECX = in->start -6986 8b/copy 0/mod/indirect 6/rm32/ESI . . . 1/r32/ECX . . # copy *ESI to ECX -6987 # end/EAX = in->end -6988 8b/copy 1/mod/*+disp8 6/rm32/ESI . . . 0/r32/EAX 4/disp8 . # copy *(ESI+4) to EAX -6989 $is-valid-name?:check0: -6990 # if (start >= end) return false -6991 39/compare 3/mod/direct 1/rm32/ECX . . . 0/r32/EAX . . # compare ECX with EAX -6992 7d/jump-if-greater-or-equal $is-valid-name?:false/disp8 -6993 $is-valid-name?:check1: -6994 # EAX -= ECX -6995 29/subtract 3/mod/direct 0/rm32/EAX . . . 1/r32/ECX . . # subtract ECX from EAX -6996 # if (EAX == 2) return false -6997 3d/compare-EAX-and 2/imm32 -6998 74/jump-if-equal $is-valid-name?:false/disp8 -6999 $is-valid-name?:check2: -7000 # c/EAX = *ECX -7001 31/xor 3/mod/direct 0/rm32/EAX . . . 0/r32/EAX . . # clear EAX -7002 8a/copy-byte 0/mod/indirect 1/rm32/ECX . . . 0/r32/AL . . # copy byte at *ECX to AL -7003 # if (c == "-") return false -7004 3d/compare-EAX-and 2d/imm32/- -7005 74/jump-if-equal $is-valid-name?:false/disp8 -7006 $is-valid-name?:check3a: -7007 # if (c < "0") return true -7008 3d/compare-EAX-with 30/imm32/0 -7009 7c/jump-if-lesser $is-valid-name?:true/disp8 -7010 $is-valid-name?:check3b: -7011 # if (c > "9") return true -7012 3d/compare-EAX-with 39/imm32/9 -7013 7f/jump-if-greater $is-valid-name?:true/disp8 -7014 $is-valid-name?:false: -7015 # return false -7016 b8/copy-to-EAX 0/imm32/false -7017 eb/jump $is-valid-name?:end/disp8 -7018 $is-valid-name?:true: -7019 # return true -7020 b8/copy-to-EAX 1/imm32/true -7021 $is-valid-name?:end: -7022 # . restore registers -7023 5e/pop-to-ESI -7024 59/pop-to-ECX -7025 # . epilog -7026 89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . . # copy EBP to ESP -7027 5d/pop-to-EBP -7028 c3/return -7029 -7030 test-is-valid-name-digit-prefix: -7031 # . prolog -7032 55/push-EBP -7033 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP -7034 # var slice/ECX = "34" -7035 68/push _test-slice-hex-int-end/imm32 -7036 68/push _test-slice-hex-int/imm32 -7037 89/copy 3/mod/direct 1/rm32/ECX . . . 4/r32/ESP . . # copy ESP to ECX -7038 # EAX = is-valid-name?(slice) -7039 # . . push args -7040 51/push-ECX -7041 # . . call -7042 e8/call is-valid-name?/disp32 -7043 # . . discard args -7044 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP -7045 # check-ints-equal(EAX, 0, msg) -7046 # . . push args -7047 68/push "F - test-is-valid-name-digit-prefix"/imm32 -7048 68/push 0/imm32/false -7049 50/push-EAX -7050 # . . call -7051 e8/call check-ints-equal/disp32 -7052 # . . discard args -7053 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP -7054 # . epilog -7055 89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . . # copy EBP to ESP -7056 5d/pop-to-EBP -7057 c3/return -7058 -7059 test-is-valid-name-negative-prefix: -7060 # . prolog -7061 55/push-EBP -7062 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP -7063 # var slice/ECX = "-0x34" -7064 68/push _test-slice-hex-int-with-0x-prefix-end/imm32 -7065 68/push _test-slice-hex-int-with-0x-prefix-negative/imm32 -7066 89/copy 3/mod/direct 1/rm32/ECX . . . 4/r32/ESP . . # copy ESP to ECX -7067 # EAX = is-valid-name?(slice) -7068 # . . push args -7069 51/push-ECX -7070 # . . call -7071 e8/call is-valid-name?/disp32 -7072 # . . discard args -7073 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP -7074 # check-ints-equal(EAX, 0, msg) -7075 # . . push args -7076 68/push "F - test-is-valid-name-negative-prefix"/imm32 -7077 68/push 0/imm32/false -7078 50/push-EAX -7079 # . . call -7080 e8/call check-ints-equal/disp32 -7081 # . . discard args -7082 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP -7083 # . epilog -7084 89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . . # copy EBP to ESP -7085 5d/pop-to-EBP -7086 c3/return -7087 -7088 test-is-valid-name-0x-prefix: -7089 # . prolog -7090 55/push-EBP -7091 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP -7092 # var slice/ECX = "0x34" -7093 68/push _test-slice-hex-int-with-0x-prefix-end/imm32 -7094 68/push _test-slice-hex-int-with-0x-prefix/imm32 -7095 89/copy 3/mod/direct 1/rm32/ECX . . . 4/r32/ESP . . # copy ESP to ECX -7096 # EAX = is-valid-name?(slice) -7097 # . . push args -7098 51/push-ECX -7099 # . . call -7100 e8/call is-valid-name?/disp32 -7101 # . . discard args -7102 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP -7103 # check-ints-equal(EAX, 0, msg) -7104 # . . push args -7105 68/push "F - test-is-valid-name-0x-prefix"/imm32 -7106 68/push 0/imm32/false -7107 50/push-EAX -7108 # . . call -7109 e8/call check-ints-equal/disp32 -7110 # . . discard args -7111 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP -7112 # . epilog -7113 89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . . # copy EBP to ESP -7114 5d/pop-to-EBP -7115 c3/return -7116 -7117 test-is-valid-name-starts-with-pre-digit: -7118 # . prolog -7119 55/push-EBP -7120 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP -7121 # var slice/ECX = "/03" -7122 68/push _test-slice-with-slash-prefix-end/imm32 -7123 68/push _test-slice-with-slash-prefix/imm32 -7124 89/copy 3/mod/direct 1/rm32/ECX . . . 4/r32/ESP . . # copy ESP to ECX -7125 # EAX = is-valid-name?(slice) +6980 # var slice/ECX = "q34" +6981 68/push _test-slice-char-and-digits-end/imm32 +6982 68/push _test-slice-char-and-digits/imm32 +6983 89/copy 3/mod/direct 1/rm32/ECX . . . 4/r32/ESP . . # copy ESP to ECX +6984 # EAX = is-valid-name?(slice) +6985 # . . push args +6986 51/push-ECX +6987 # . . call +6988 e8/call is-valid-name?/disp32 +6989 # . . discard args +6990 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP +6991 # check-ints-equal(EAX, 1, msg) +6992 # . . push args +6993 68/push "F - test-is-valid-name-starts-with-post-digit"/imm32 +6994 68/push 1/imm32/true +6995 50/push-EAX +6996 # . . call +6997 e8/call check-ints-equal/disp32 +6998 # . . discard args +6999 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP +7000 # . epilog +7001 89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . . # copy EBP to ESP +7002 5d/pop-to-EBP +7003 c3/return +7004 +7005 test-is-valid-name-starts-with-digit: +7006 # . prolog +7007 55/push-EBP +7008 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP +7009 # var slice/ECX = "0x34" +7010 68/push _test-slice-hex-int-with-0x-prefix-end/imm32 +7011 68/push _test-slice-hex-int-with-0x-prefix/imm32 +7012 89/copy 3/mod/direct 1/rm32/ECX . . . 4/r32/ESP . . # copy ESP to ECX +7013 # EAX = is-valid-name?(slice) +7014 # . . push args +7015 51/push-ECX +7016 # . . call +7017 e8/call is-valid-name?/disp32 +7018 # . . discard args +7019 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP +7020 # check-ints-equal(EAX, 0, msg) +7021 # . . push args +7022 68/push "F - test-is-valid-name-starts-with-digit"/imm32 +7023 68/push 0/imm32/false +7024 50/push-EAX +7025 # . . call +7026 e8/call check-ints-equal/disp32 +7027 # . . discard args +7028 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP +7029 # . epilog +7030 89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . . # copy EBP to ESP +7031 5d/pop-to-EBP +7032 c3/return +7033 +7034 # print 'n' in hex in 'width' bytes in lower-endian order, with a space after every byte +7035 emit-hex: # out : (address buffered-file), n : int, width : int -> <void> +7036 # . prolog +7037 55/push-EBP +7038 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP +7039 # . save registers +7040 50/push-EAX +7041 51/push-ECX +7042 52/push-EDX +7043 53/push-EBX +7044 57/push-EDI +7045 # EDI = out +7046 8b/copy 1/mod/*+disp8 5/rm32/EBP . . . 7/r32/EDI 8/disp8 . # copy *(EBP+8) to EDI +7047 # EBX = n +7048 8b/copy 1/mod/*+disp8 5/rm32/EBP . . . 3/r32/EBX 0xc/disp8 . # copy *(EBP+12) to EBX +7049 # EDX = width +7050 8b/copy 1/mod/*+disp8 5/rm32/EBP . . . 2/r32/EDX 0x10/disp8 . # copy *(EBP+16) to EDX +7051 # var curr/ECX = 0 +7052 31/xor 3/mod/direct 1/rm32/ECX . . . 1/r32/ECX . . # clear ECX +7053 $emit-hex:loop: +7054 # if (curr >= width) break +7055 39/compare 3/mod/direct 1/rm32/ECX . . . 2/r32/EDX . . # compare ECX with EDX +7056 7d/jump-if-greater-or-equal $emit-hex:end/disp8 +7057 # print-byte(out, EBX) +7058 # . . push args +7059 53/push-EBX +7060 57/push-EDI +7061 # . . call +7062 e8/call print-byte/disp32 +7063 # . . discard args +7064 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP +7065 # write-byte(out, ' ') +7066 # . . push args +7067 68/push 0x20/imm32/space +7068 57/push-EDI +7069 # . . call +7070 e8/call write-byte/disp32 +7071 # . . discard args +7072 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP +7073 # EBX = EBX >> 8 +7074 c1/shift 5/subop/logic-right 3/mod/direct 3/rm32/EBX . . . . . 8/imm8 # shift EBX right by 8 bits, while padding zeroes +7075 $emit-hex:continue: +7076 # ++curr +7077 41/increment-ECX +7078 eb/jump $emit-hex:loop/disp8 +7079 $emit-hex:end: +7080 # . restore registers +7081 5f/pop-to-EDI +7082 5b/pop-to-EBX +7083 5a/pop-to-EDX +7084 59/pop-to-ECX +7085 58/pop-to-EAX +7086 # . epilog +7087 89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . . # copy EBP to ESP +7088 5d/pop-to-EBP +7089 c3/return +7090 +7091 test-emit-hex-single-byte: +7092 # setup +7093 # . clear-stream(_test-output-stream) +7094 # . . push args +7095 68/push _test-output-stream/imm32 +7096 # . . call +7097 e8/call clear-stream/disp32 +7098 # . . discard args +7099 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP +7100 # . clear-stream(_test-output-buffered-file+4) +7101 # . . push args +7102 b8/copy-to-EAX _test-output-buffered-file/imm32 +7103 05/add-to-EAX 4/imm32 +7104 50/push-EAX +7105 # . . call +7106 e8/call clear-stream/disp32 +7107 # . . discard args +7108 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP +7109 # emit-hex(_test-output-buffered-file, 0xab, 1) +7110 # . . push args +7111 68/push 1/imm32 +7112 68/push 0xab/imm32 +7113 68/push _test-output-buffered-file/imm32 +7114 # . . call +7115 e8/call emit-hex/disp32 +7116 # . . discard args +7117 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP +7118 # flush(_test-output-buffered-file) +7119 # . . push args +7120 68/push _test-output-buffered-file/imm32 +7121 # . . call +7122 e8/call flush/disp32 +7123 # . . discard args +7124 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP +7125 # check-ints-equal(*_test-output-stream->data, 'ab ', msg) 7126 # . . push args -7127 51/push-ECX -7128 # . . call -7129 e8/call is-valid-name?/disp32 -7130 # . . discard args -7131 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP -7132 # check-ints-equal(EAX, 1, msg) -7133 # . . push args -7134 68/push "F - test-is-valid-name-starts-with-pre-digit"/imm32 -7135 68/push 1/imm32/true -7136 50/push-EAX -7137 # . . call -7138 e8/call check-ints-equal/disp32 -7139 # . . discard args -7140 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP -7141 # . epilog -7142 89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . . # copy EBP to ESP -7143 5d/pop-to-EBP -7144 c3/return -7145 -7146 test-is-valid-name-starts-with-post-digit: -7147 # . prolog -7148 55/push-EBP -7149 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP -7150 # var slice/ECX = "q34" -7151 68/push _test-slice-char-and-digits-end/imm32 -7152 68/push _test-slice-char-and-digits/imm32 -7153 89/copy 3/mod/direct 1/rm32/ECX . . . 4/r32/ESP . . # copy ESP to ECX -7154 # EAX = is-valid-name?(slice) -7155 # . . push args -7156 51/push-ECX -7157 # . . call -7158 e8/call is-valid-name?/disp32 -7159 # . . discard args -7160 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP -7161 # check-ints-equal(EAX, 1, msg) -7162 # . . push args -7163 68/push "F - test-is-valid-name-starts-with-post-digit"/imm32 -7164 68/push 1/imm32/true -7165 50/push-EAX -7166 # . . call -7167 e8/call check-ints-equal/disp32 -7168 # . . discard args -7169 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP -7170 # . epilog -7171 89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . . # copy EBP to ESP -7172 5d/pop-to-EBP -7173 c3/return -7174 -7175 test-is-valid-name-starts-with-digit: -7176 # . prolog -7177 55/push-EBP -7178 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP -7179 # var slice/ECX = "0x34" -7180 68/push _test-slice-hex-int-with-0x-prefix-end/imm32 -7181 68/push _test-slice-hex-int-with-0x-prefix/imm32 -7182 89/copy 3/mod/direct 1/rm32/ECX . . . 4/r32/ESP . . # copy ESP to ECX -7183 # EAX = is-valid-name?(slice) -7184 # . . push args -7185 51/push-ECX -7186 # . . call -7187 e8/call is-valid-name?/disp32 -7188 # . . discard args -7189 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP -7190 # check-ints-equal(EAX, 0, msg) -7191 # . . push args -7192 68/push "F - test-is-valid-name-starts-with-digit"/imm32 -7193 68/push 0/imm32/false -7194 50/push-EAX -7195 # . . call -7196 e8/call check-ints-equal/disp32 -7197 # . . discard args -7198 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP -7199 # . epilog -7200 89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . . # copy EBP to ESP -7201 5d/pop-to-EBP -7202 c3/return -7203 -7204 # print 'n' in hex in 'width' bytes in lower-endian order, with a space after every byte -7205 emit-hex: # out : (address buffered-file), n : int, width : int -> <void> -7206 # . prolog -7207 55/push-EBP -7208 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP -7209 # . save registers -7210 50/push-EAX -7211 51/push-ECX -7212 52/push-EDX -7213 53/push-EBX -7214 57/push-EDI -7215 # EDI = out -7216 8b/copy 1/mod/*+disp8 5/rm32/EBP . . . 7/r32/EDI 8/disp8 . # copy *(EBP+8) to EDI -7217 # EBX = n -7218 8b/copy 1/mod/*+disp8 5/rm32/EBP . . . 3/r32/EBX 0xc/disp8 . # copy *(EBP+12) to EBX -7219 # EDX = width -7220 8b/copy 1/mod/*+disp8 5/rm32/EBP . . . 2/r32/EDX 0x10/disp8 . # copy *(EBP+16) to EDX -7221 # var curr/ECX = 0 -7222 31/xor 3/mod/direct 1/rm32/ECX . . . 1/r32/ECX . . # clear ECX -7223 $emit-hex:loop: -7224 # if (curr >= width) break -7225 39/compare 3/mod/direct 1/rm32/ECX . . . 2/r32/EDX . . # compare ECX and EDX -7226 7d/jump-if-greater-or-equal $emit-hex:end/disp8 -7227 # print-byte(out, EBX) -7228 # . . push args -7229 53/push-EBX -7230 57/push-EDI -7231 # . . call -7232 e8/call print-byte/disp32 -7233 # . . discard args -7234 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP -7235 # write-byte(out, ' ') -7236 # . . push args -7237 68/push 0x20/imm32/space -7238 57/push-EDI -7239 # . . call -7240 e8/call write-byte/disp32 -7241 # . . discard args -7242 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP -7243 # EBX = EBX >> 8 -7244 c1/shift 5/subop/logic-right 3/mod/direct 3/rm32/EBX . . . . . 8/imm8 # shift EBX right by 8 bits, while padding zeroes -7245 $emit-hex:continue: -7246 # ++curr -7247 41/increment-ECX -7248 eb/jump $emit-hex:loop/disp8 -7249 $emit-hex:end: -7250 # . restore registers -7251 5f/pop-to-EDI -7252 5b/pop-to-EBX -7253 5a/pop-to-EDX -7254 59/pop-to-ECX -7255 58/pop-to-EAX -7256 # . epilog -7257 89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . . # copy EBP to ESP -7258 5d/pop-to-EBP -7259 c3/return -7260 -7261 test-emit-hex-single-byte: -7262 # setup -7263 # . clear-stream(_test-output-stream) -7264 # . . push args -7265 68/push _test-output-stream/imm32 -7266 # . . call -7267 e8/call clear-stream/disp32 -7268 # . . discard args -7269 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP -7270 # . clear-stream(_test-output-buffered-file+4) -7271 # . . push args -7272 b8/copy-to-EAX _test-output-buffered-file/imm32 -7273 05/add-to-EAX 4/imm32 -7274 50/push-EAX -7275 # . . call -7276 e8/call clear-stream/disp32 -7277 # . . discard args -7278 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP -7279 # emit-hex(_test-output-buffered-file, 0xab, 1) -7280 # . . push args -7281 68/push 1/imm32 -7282 68/push 0xab/imm32 -7283 68/push _test-output-buffered-file/imm32 -7284 # . . call -7285 e8/call emit-hex/disp32 -7286 # . . discard args -7287 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP -7288 # flush(_test-output-buffered-file) -7289 # . . push args -7290 68/push _test-output-buffered-file/imm32 -7291 # . . call -7292 e8/call flush/disp32 -7293 # . . discard args -7294 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP -7295 # check-ints-equal(*_test-output-stream->data, 'ab ', msg) -7296 # . . push args -7297 68/push "F - test-emit-hex-single-byte"/imm32 -7298 68/push 0x206261/imm32 -7299 # . . push *_test-output-stream->data -7300 b8/copy-to-EAX _test-output-stream/imm32 -7301 ff 6/subop/push 1/mod/*+disp8 0/rm32/EAX . . . . 0xc/disp8 . # push *(EAX+12) -7302 # . . call -7303 e8/call check-ints-equal/disp32 -7304 # . . discard args -7305 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP -7306 # . end -7307 c3/return -7308 -7309 test-emit-hex-multiple-byte: -7310 # setup -7311 # . clear-stream(_test-output-stream) -7312 # . . push args -7313 68/push _test-output-stream/imm32 -7314 # . . call -7315 e8/call clear-stream/disp32 -7316 # . . discard args -7317 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP -7318 # . clear-stream(_test-output-buffered-file+4) -7319 # . . push args -7320 b8/copy-to-EAX _test-output-buffered-file/imm32 -7321 05/add-to-EAX 4/imm32 -7322 50/push-EAX -7323 # . . call -7324 e8/call clear-stream/disp32 -7325 # . . discard args -7326 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP -7327 # emit-hex(_test-output-buffered-file, 0x1234, 2) -7328 # . . push args -7329 68/push 2/imm32 -7330 68/push 0x1234/imm32 -7331 68/push _test-output-buffered-file/imm32 -7332 # . . call -7333 e8/call emit-hex/disp32 -7334 # . . discard args -7335 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP -7336 # flush(_test-output-buffered-file) -7337 # . . push args -7338 68/push _test-output-buffered-file/imm32 -7339 # . . call -7340 e8/call flush/disp32 -7341 # . . discard args -7342 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP -7343 # check-stream-equal(_test-output-stream, "34 12 ", msg) -7344 # . . push args -7345 68/push "F - test-emit-hex-multiple-byte/1"/imm32 -7346 68/push "34 12 "/imm32 -7347 68/push _test-output-stream/imm32 -7348 # . . call -7349 e8/call check-stream-equal/disp32 -7350 # . . discard args -7351 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP -7352 # . end -7353 c3/return -7354 -7355 test-emit-hex-zero-pad: -7356 # setup -7357 # . clear-stream(_test-output-stream) -7358 # . . push args -7359 68/push _test-output-stream/imm32 -7360 # . . call -7361 e8/call clear-stream/disp32 -7362 # . . discard args -7363 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP -7364 # . clear-stream(_test-output-buffered-file+4) -7365 # . . push args -7366 b8/copy-to-EAX _test-output-buffered-file/imm32 -7367 05/add-to-EAX 4/imm32 -7368 50/push-EAX -7369 # . . call -7370 e8/call clear-stream/disp32 -7371 # . . discard args -7372 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP -7373 # emit-hex(_test-output-buffered-file, 0xab, 2) -7374 # . . push args -7375 68/push 2/imm32 -7376 68/push 0xab/imm32 -7377 68/push _test-output-buffered-file/imm32 -7378 # . . call -7379 e8/call emit-hex/disp32 -7380 # . . discard args -7381 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP -7382 # flush(_test-output-buffered-file) -7383 # . . push args -7384 68/push _test-output-buffered-file/imm32 -7385 # . . call -7386 e8/call flush/disp32 -7387 # . . discard args -7388 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP -7389 # check(_test-output-stream->data == 'ab 00 ') -7390 # . . push args -7391 68/push "F - test-emit-hex-zero-pad/1"/imm32 -7392 68/push "ab 00 "/imm32 -7393 68/push _test-output-stream/imm32 -7394 # . . call -7395 e8/call check-stream-equal/disp32 -7396 # . . discard args -7397 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP -7398 # . end -7399 c3/return -7400 -7401 test-emit-hex-negative: -7402 # setup -7403 # . clear-stream(_test-output-stream) -7404 # . . push args -7405 68/push _test-output-stream/imm32 -7406 # . . call -7407 e8/call clear-stream/disp32 -7408 # . . discard args -7409 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP -7410 # . clear-stream(_test-output-buffered-file+4) -7411 # . . push args -7412 b8/copy-to-EAX _test-output-buffered-file/imm32 -7413 05/add-to-EAX 4/imm32 -7414 50/push-EAX -7415 # . . call -7416 e8/call clear-stream/disp32 -7417 # . . discard args -7418 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP -7419 # emit-hex(_test-output-buffered-file, -1, 2) -7420 # . . push args -7421 68/push 2/imm32 -7422 68/push -1/imm32 -7423 68/push _test-output-buffered-file/imm32 -7424 # . . call -7425 e8/call emit-hex/disp32 -7426 # . . discard args -7427 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP -7428 # flush(_test-output-buffered-file) -7429 # . . push args -7430 68/push _test-output-buffered-file/imm32 -7431 # . . call -7432 e8/call flush/disp32 -7433 # . . discard args -7434 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP -7435 # check-stream-equal(_test-output-stream == "ff ff ") -7436 # . . push args -7437 68/push "F - test-emit-hex-negative/1"/imm32 -7438 68/push "ff ff "/imm32 -7439 68/push _test-output-stream/imm32 -7440 # . . call -7441 e8/call check-stream-equal/disp32 -7442 # . . discard args -7443 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP -7444 # . end -7445 c3/return -7446 -7447 # write an entire stream's contents to a buffered-file -7448 # ways to do this: -7449 # - construct a 'maximal slice' and pass it to write-slice -7450 # - flush the buffered-file and pass the stream directly to its fd (disabling buffering) -7451 # we'll go with the first way for now -7452 write-stream-data: # f : (address buffered-file), s : (address stream) -> <void> -7453 # . prolog -7454 55/push-EBP -7455 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP -7456 # . save registers -7457 50/push-EAX -7458 51/push-ECX -7459 56/push-ESI -7460 # ESI = s -7461 8b/copy 1/mod/*+disp8 5/rm32/EBP . . . 6/r32/ESI 0xc/disp8 . # copy *(EBP+12) to ESI -7462 # var slice/ECX = {s->data, s->data + s->write} -7463 # . push s->data + s->write -7464 8b/copy 0/mod/indirect 6/rm32/ESI . . . 0/r32/EAX . . # copy *ESI to EAX -7465 8d/copy-address 1/mod/*+disp8 4/rm32/sib 6/base/ESI 0/index/EAX . 0/r32/EAX 0xc/disp8 . # copy ESI+EAX+12 to EAX -7466 50/push-EAX -7467 # . push s->data -7468 8d/copy-address 1/mod/*+disp8 6/rm32/ESI . . . 0/r32/EAX 0xc/disp8 . # copy ESI+12 to EAX -7469 50/push-EAX -7470 # . ECX = ESP -7471 89/copy 3/mod/direct 1/rm32/ECX . . . 4/r32/ESP . . # copy ESP to ECX -7472 # write-slice(f, slice) -7473 # . . push args -7474 51/push-ECX -7475 ff 6/subop/push 1/mod/*+disp8 5/rm32/EBP . . . . 8/disp8 . # push *(EBP+8) -7476 # . . call -7477 e8/call write-slice/disp32 -7478 # . . discard args -7479 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP -7480 $write-stream-data:end: -7481 # . restore locals -7482 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP -7483 # . restore registers -7484 5e/pop-to-ESI -7485 59/pop-to-ECX -7486 58/pop-to-EAX -7487 # . epilog -7488 89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . . # copy EBP to ESP -7489 5d/pop-to-EBP -7490 c3/return -7491 -7492 test-write-stream-data: -7493 # . prolog -7494 55/push-EBP -7495 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP -7496 # setup -7497 # . clear-stream(_test-output-stream) -7498 # . . push args -7499 68/push _test-output-stream/imm32 -7500 # . . call -7501 e8/call clear-stream/disp32 -7502 # . . discard args -7503 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP -7504 # . clear-stream(_test-output-buffered-file+4) -7505 # . . push args -7506 b8/copy-to-EAX _test-output-buffered-file/imm32 -7507 05/add-to-EAX 4/imm32 -7508 50/push-EAX -7509 # . . call -7510 e8/call clear-stream/disp32 -7511 # . . discard args -7512 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP -7513 # . clear-stream(_test-tmp-stream) -7514 # . . push args -7515 68/push _test-tmp-stream/imm32 -7516 # . . call -7517 e8/call clear-stream/disp32 -7518 # . . discard args -7519 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP -7520 # initialize input -7521 # . write(_test-tmp-stream, "abcd") -7522 # . . push args -7523 68/push "abcd"/imm32 -7524 68/push _test-tmp-stream/imm32 -7525 # . . call -7526 e8/call write/disp32 -7527 # . . discard args -7528 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP -7529 # write-stream-data(_test-output-buffered-file, _test-tmp-stream) -7530 # . . push args -7531 68/push _test-tmp-stream/imm32 -7532 68/push _test-output-buffered-file/imm32 -7533 # . . call -7534 e8/call write-stream-data/disp32 -7535 # . . discard args -7536 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP -7537 # check that the write happened as expected -7538 # . flush(_test-output-buffered-file) -7539 # . . push args -7540 68/push _test-output-buffered-file/imm32 -7541 # . . call -7542 e8/call flush/disp32 -7543 # . . discard args -7544 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP -7545 # . check-stream-equal(_test-output-stream, "abcd", msg) -7546 # . . push args -7547 68/push "F - test-write-stream-data"/imm32 -7548 68/push "abcd"/imm32 -7549 68/push _test-output-stream/imm32 -7550 # . . call -7551 e8/call check-stream-equal/disp32 -7552 # . . discard args -7553 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP -7554 # . epilog -7555 89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . . # copy EBP to ESP -7556 5d/pop-to-EBP -7557 c3/return -7558 -7559 # shortcut for parse-hex-int(next-token-from-slice(word->start, word->end, '/')) -7560 parse-datum-of-word: # word : (address slice) -> value/EAX -7561 # . prolog -7562 55/push-EBP -7563 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP -7564 # . save registers -7565 51/push-ECX -7566 56/push-ESI -7567 # ESI = word -7568 8b/copy 1/mod/*+disp8 5/rm32/EBP . . . 6/r32/ESI 8/disp8 . # copy *(EBP+8) to ESI -7569 # var slice/ECX = {0, 0} -7570 68/push 0/imm32/end -7571 68/push 0/imm32/start -7572 89/copy 3/mod/direct 1/rm32/ECX . . . 4/r32/ESP . . # copy ESP to ECX -7573 # slice = next-token-from-slice(word->start, word->end, '/') -7574 # . . push args -7575 51/push-ECX -7576 68/push 0x2f/imm32/slash -7577 ff 6/subop/push 1/mod/*+disp8 6/rm32/ESI . . . . 4/disp8 . # push *(ESI+4) -7578 ff 6/subop/push 0/mod/indirect 6/rm32/ESI . . . . . . # push *ESI -7579 # . . call -7580 e8/call next-token-from-slice/disp32 -7581 # . . discard args -7582 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0x10/imm32 # add to ESP -7583 # value/EAX = parse-hex-int(slice) -7584 # . . push args -7585 51/push-ECX -7586 # . . call -7587 e8/call parse-hex-int/disp32 -7588 # . . discard args -7589 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP -7590 $parse-datum-of-word:end: -7591 # . reclaim locals -7592 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP -7593 # . restore registers -7594 5e/pop-to-ESI -7595 59/pop-to-ECX -7596 # . epilog -7597 89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . . # copy EBP to ESP -7598 5d/pop-to-EBP -7599 c3/return -7600 -7601 == data -7602 -7603 _test-slice-negative-two: -7604 2d/- 32/2 -7605 _test-slice-negative-two-end: -7606 2f/slash 66/f 6f/o 6f/o -7607 _test-slice-negative-two-metadata-end: -7608 -7609 _test-slice-three-zero: -7610 33/3 30/0 -7611 _test-slice-three-zero-end: -7612 -7613 _test-slice-non-number-word: -7614 78/x 79/y 7a/z -7615 _test-slice-non-number-word-end: -7616 2f/slash -7617 _test-slice-non-number-word-metadata-end: -7618 -7619 _test-input-stream: -7620 # current write index -7621 0/imm32 -7622 # current read index -7623 0/imm32 -7624 # length -7625 0x80/imm32 # 128 bytes -7626 # data (8 lines x 16 bytes/line) -7627 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -7628 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -7629 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -7630 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -7631 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -7632 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -7633 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -7634 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -7635 -7636 # a test buffered file for _test-input-stream -7637 _test-input-buffered-file: -7638 # file descriptor or (address stream) -7639 _test-input-stream/imm32 -7640 # current write index -7641 0/imm32 -7642 # current read index -7643 0/imm32 -7644 # length -7645 6/imm32 -7646 # data -7647 00 00 00 00 00 00 # 6 bytes -7648 -7649 _test-output-stream: -7650 # current write index -7651 0/imm32 -7652 # current read index -7653 0/imm32 -7654 # length -7655 0x80/imm32 # 128 bytes -7656 # data (8 lines x 16 bytes/line) -7657 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -7658 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -7659 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -7660 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -7661 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -7662 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -7663 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -7664 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -7665 -7666 # a test buffered file for _test-output-stream -7667 _test-output-buffered-file: -7668 # file descriptor or (address stream) -7669 _test-output-stream/imm32 -7670 # current write index -7671 0/imm32 -7672 # current read index -7673 0/imm32 -7674 # length -7675 6/imm32 -7676 # data -7677 00 00 00 00 00 00 # 6 bytes -7678 -7679 _test-slice-hexlike-non-number-word: -7680 61/a 62/b 63/c 64/d -7681 _test-slice-hexlike-non-number-word-end: -7682 2f/slash -7683 78/x 79/y 7a/z -7684 _test-slice-hexlike-non-number-word-metadata-end: -7685 -7686 _test-slice-with-slash-prefix: -7687 2f/slash 30/0 33/3 -7688 _test-slice-with-slash-prefix-end: -7689 -7690 # . . vim:nowrap:textwidth=0 +7127 68/push "F - test-emit-hex-single-byte"/imm32 +7128 68/push 0x206261/imm32 +7129 # . . push *_test-output-stream->data +7130 b8/copy-to-EAX _test-output-stream/imm32 +7131 ff 6/subop/push 1/mod/*+disp8 0/rm32/EAX . . . . 0xc/disp8 . # push *(EAX+12) +7132 # . . call +7133 e8/call check-ints-equal/disp32 +7134 # . . discard args +7135 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP +7136 # . end +7137 c3/return +7138 +7139 test-emit-hex-multiple-byte: +7140 # setup +7141 # . clear-stream(_test-output-stream) +7142 # . . push args +7143 68/push _test-output-stream/imm32 +7144 # . . call +7145 e8/call clear-stream/disp32 +7146 # . . discard args +7147 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP +7148 # . clear-stream(_test-output-buffered-file+4) +7149 # . . push args +7150 b8/copy-to-EAX _test-output-buffered-file/imm32 +7151 05/add-to-EAX 4/imm32 +7152 50/push-EAX +7153 # . . call +7154 e8/call clear-stream/disp32 +7155 # . . discard args +7156 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP +7157 # emit-hex(_test-output-buffered-file, 0x1234, 2) +7158 # . . push args +7159 68/push 2/imm32 +7160 68/push 0x1234/imm32 +7161 68/push _test-output-buffered-file/imm32 +7162 # . . call +7163 e8/call emit-hex/disp32 +7164 # . . discard args +7165 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP +7166 # flush(_test-output-buffered-file) +7167 # . . push args +7168 68/push _test-output-buffered-file/imm32 +7169 # . . call +7170 e8/call flush/disp32 +7171 # . . discard args +7172 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP +7173 # check-stream-equal(_test-output-stream, "34 12 ", msg) +7174 # . . push args +7175 68/push "F - test-emit-hex-multiple-byte/1"/imm32 +7176 68/push "34 12 "/imm32 +7177 68/push _test-output-stream/imm32 +7178 # . . call +7179 e8/call check-stream-equal/disp32 +7180 # . . discard args +7181 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP +7182 # . end +7183 c3/return +7184 +7185 test-emit-hex-zero-pad: +7186 # setup +7187 # . clear-stream(_test-output-stream) +7188 # . . push args +7189 68/push _test-output-stream/imm32 +7190 # . . call +7191 e8/call clear-stream/disp32 +7192 # . . discard args +7193 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP +7194 # . clear-stream(_test-output-buffered-file+4) +7195 # . . push args +7196 b8/copy-to-EAX _test-output-buffered-file/imm32 +7197 05/add-to-EAX 4/imm32 +7198 50/push-EAX +7199 # . . call +7200 e8/call clear-stream/disp32 +7201 # . . discard args +7202 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP +7203 # emit-hex(_test-output-buffered-file, 0xab, 2) +7204 # . . push args +7205 68/push 2/imm32 +7206 68/push 0xab/imm32 +7207 68/push _test-output-buffered-file/imm32 +7208 # . . call +7209 e8/call emit-hex/disp32 +7210 # . . discard args +7211 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP +7212 # flush(_test-output-buffered-file) +7213 # . . push args +7214 68/push _test-output-buffered-file/imm32 +7215 # . . call +7216 e8/call flush/disp32 +7217 # . . discard args +7218 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP +7219 # check(_test-output-stream->data == 'ab 00 ') +7220 # . . push args +7221 68/push "F - test-emit-hex-zero-pad/1"/imm32 +7222 68/push "ab 00 "/imm32 +7223 68/push _test-output-stream/imm32 +7224 # . . call +7225 e8/call check-stream-equal/disp32 +7226 # . . discard args +7227 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP +7228 # . end +7229 c3/return +7230 +7231 test-emit-hex-negative: +7232 # setup +7233 # . clear-stream(_test-output-stream) +7234 # . . push args +7235 68/push _test-output-stream/imm32 +7236 # . . call +7237 e8/call clear-stream/disp32 +7238 # . . discard args +7239 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP +7240 # . clear-stream(_test-output-buffered-file+4) +7241 # . . push args +7242 b8/copy-to-EAX _test-output-buffered-file/imm32 +7243 05/add-to-EAX 4/imm32 +7244 50/push-EAX +7245 # . . call +7246 e8/call clear-stream/disp32 +7247 # . . discard args +7248 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP +7249 # emit-hex(_test-output-buffered-file, -1, 2) +7250 # . . push args +7251 68/push 2/imm32 +7252 68/push -1/imm32 +7253 68/push _test-output-buffered-file/imm32 +7254 # . . call +7255 e8/call emit-hex/disp32 +7256 # . . discard args +7257 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP +7258 # flush(_test-output-buffered-file) +7259 # . . push args +7260 68/push _test-output-buffered-file/imm32 +7261 # . . call +7262 e8/call flush/disp32 +7263 # . . discard args +7264 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP +7265 # check-stream-equal(_test-output-stream == "ff ff ") +7266 # . . push args +7267 68/push "F - test-emit-hex-negative/1"/imm32 +7268 68/push "ff ff "/imm32 +7269 68/push _test-output-stream/imm32 +7270 # . . call +7271 e8/call check-stream-equal/disp32 +7272 # . . discard args +7273 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP +7274 # . end +7275 c3/return +7276 +7277 # shortcut for parse-hex-int(next-token-from-slice(word->start, word->end, '/')) +7278 parse-datum-of-word: # word : (address slice) -> value/EAX +7279 # . prolog +7280 55/push-EBP +7281 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP +7282 # . save registers +7283 51/push-ECX +7284 56/push-ESI +7285 # ESI = word +7286 8b/copy 1/mod/*+disp8 5/rm32/EBP . . . 6/r32/ESI 8/disp8 . # copy *(EBP+8) to ESI +7287 # var slice/ECX = {0, 0} +7288 68/push 0/imm32/end +7289 68/push 0/imm32/start +7290 89/copy 3/mod/direct 1/rm32/ECX . . . 4/r32/ESP . . # copy ESP to ECX +7291 # slice = next-token-from-slice(word->start, word->end, '/') +7292 # . . push args +7293 51/push-ECX +7294 68/push 0x2f/imm32/slash +7295 ff 6/subop/push 1/mod/*+disp8 6/rm32/ESI . . . . 4/disp8 . # push *(ESI+4) +7296 ff 6/subop/push 0/mod/indirect 6/rm32/ESI . . . . . . # push *ESI +7297 # . . call +7298 e8/call next-token-from-slice/disp32 +7299 # . . discard args +7300 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0x10/imm32 # add to ESP +7301 # value/EAX = parse-hex-int(slice) +7302 # . . push args +7303 51/push-ECX +7304 # . . call +7305 e8/call parse-hex-int/disp32 +7306 # . . discard args +7307 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP +7308 $parse-datum-of-word:end: +7309 # . reclaim locals +7310 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP +7311 # . restore registers +7312 5e/pop-to-ESI +7313 59/pop-to-ECX +7314 # . epilog +7315 89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . . # copy EBP to ESP +7316 5d/pop-to-EBP +7317 c3/return +7318 +7319 == data +7320 +7321 _test-slice-negative-two: +7322 2d/- 32/2 +7323 _test-slice-negative-two-end: +7324 2f/slash 66/f 6f/o 6f/o +7325 _test-slice-negative-two-metadata-end: +7326 +7327 _test-slice-three-zero: +7328 33/3 30/0 +7329 _test-slice-three-zero-end: +7330 +7331 _test-slice-non-number-word: +7332 78/x 79/y 7a/z +7333 _test-slice-non-number-word-end: +7334 2f/slash +7335 _test-slice-non-number-word-metadata-end: +7336 +7337 _test-slice-hexlike-non-number-word: +7338 61/a 62/b 63/c 64/d +7339 _test-slice-hexlike-non-number-word-end: +7340 2f/slash +7341 78/x 79/y 7a/z +7342 _test-slice-hexlike-non-number-word-metadata-end: +7343 +7344 _test-slice-with-slash-prefix: +7345 2f/slash 30/0 33/3 +7346 _test-slice-with-slash-prefix-end: +7347 +7348 # . . vim:nowrap:textwidth=0 -- cgit 1.4.1-2-gfad0