# Rudimentary test harness == code # instruction effective address operand displacement immediate # op subop mod rm32 base index scale r32 # 1-3 bytes 3 bits 2 bits 3 bits 3 bits 3 bits 2 bits 2 bits 0/1/2/4 bytes 0/1/2/4 bytes # main: (manual test if this is the last file loaded) # check-ints-equal(34, 34) == 1 68/push "error in check-ints-equal"/imm32 68/push 35/imm32 68/push 34/imm32 e8/call check-ints-equal/disp32 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP # syscall(exit, 0) bb/copy-to-EBX 0/imm32 b8/copy-to-EAX 1/imm32 cd/syscall 0x80/imm8 # print msg to stderr if a != b, otherwise print "." check-ints-equal: # (a : int, b : int, msg : (address array byte)) -> boolean # prolog 55/push-EBP 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP # save registers 51/push-ECX 53/push-EBX # load first 2 args into EAX and EBX 8b/copy 1/mod/*+disp8 4/rm32/sib 5/base/EBP 4/index/none . 0/r32/EAX 0x8/disp8 . # copy *(EBP+8) to EAX 8b/copy 1/mod/*+disp8 4/rm32/sib 5/base/EBP 4/index/none . 3/r32/EBX 0xc/disp8 . # copy *(EBP+12) to EBX # if EAX == b/EBX 39/compare 3/mod/direct 0/rm32/EAX . . . 3/r32/EBX . . # compare EAX and EBX 75/jump-if-unequal $check-ints-equal:else/disp8 # _write(2/stderr, '.') # push args 68/push "."/imm32 68/push 2/imm32/stderr # call e8/call _write/disp32 # discard arg 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP # return eb/jump $check-ints-equal:end/disp8 # else: $check-ints-equal:else: # copy third arg (msg) into ECX 8b/copy 1/mod/*+disp8 4/rm32/sib 5/base/EBP 4/index/none . 1/r32/ECX 0x10/disp8 . # copy *(EBP+16) to ECX # _write(2/stderr, ECX) # push args 51/push-ECX 68/push 2/imm32/stderr # call e8/call _write/disp32 # discard arg 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP # print newline # push args 68/push Newline/imm32 68/push 2/imm32/stderr # call e8/call _write/disp32 # discard arg 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP # increment Num-test-failures ff 0/subop/increment 0/mod/indirect 5/rm32/.disp32 . . . Num-test-failures/disp32 # increment *Num-test-failures $check-ints-equal:end: # restore registers 5b/pop-to-EBX 59/pop-to-ECX # epilog 89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . . # copy EBP to ESP 5d/pop-to-EBP c3/return == data Newline: # size 01 00 00 00 # data 0a/newline Num-test-failures: 00 00 00 00 # vim:nowrap:textwidth=0