1 # Print an error message followed by the text representation of a byte. Then exit. 2 3 == code 4 # instruction effective address register displacement immediate 5 # . op subop mod rm32 base index scale r32 6 # . 1-3 bytes 3 bits 2 bits 3 bits 3 bits 3 bits 2 bits 2 bits 0/1/2/4 bytes 0/1/2/4 bytes 7 8 #? Entry: # manual test 9 #? # . var ed/eax: exit-descriptor 10 #? 81 5/subop/subtract 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # subtract from esp 11 #? 89/copy 3/mod/direct 0/rm32/eax . . . 4/r32/esp . . # copy esp to eax 12 #? # . configure ed to really exit() 13 #? # . . ed->target = 0 14 #? c7 0/subop/copy 0/mod/direct 0/rm32/eax . . . . . 0/imm32 # copy to *eax 15 #? # . error-byte(ed, Stdout, msg, 34) 16 #? 68/push 0x34/imm32 17 #? 68/push "abc"/imm32 18 #? 68/push Stderr/imm32 19 #? 50/push-eax 20 #? e8/call error-byte/disp32 21 #? # . syscall_exit(Num-test-failures) 22 #? 8b/copy 0/mod/indirect 5/rm32/.disp32 . . 3/r32/ebx Num-test-failures/disp32 # copy *Num-test-failures to ebx 23 #? e8/call syscall_exit/disp32 24 25 # write(out, "Error: "+msg+": "+byte) then stop(ed, 1) 26 error-byte: # ed: (addr exit-descriptor), out: (addr buffered-file), msg: (addr array byte), n: byte 27 # . prologue 28 55/push-ebp 29 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp 30 # write-buffered(out, "Error: ") 31 # . . push args 32 68/push "Error: "/imm32 33 ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp . . . . 0xc/disp8 . # push *(ebp+12) 34 # . . call 35 e8/call write-buffered/disp32 36 # . . discard args 37 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp 38 # write-buffered(out, msg) 39 # . . push args 40 ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp . . . . 0x10/disp8 . # push *(ebp+16) 41 ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp . . . . 0xc/disp8 . # push *(ebp+12) 42 # . . call 43 e8/call write-buffered/disp32 44 # . . discard args 45 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp 46 # write-buffered(out, ": ") 47 # . . push args 48 68/push ": "/imm32 49 ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp . . . . 0xc/disp8 . # push *(ebp+12) 50 # . . call 51 e8/call write-buffered/disp32 52 # . . discard args 53 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp 54 # write-byte-hex-buffered(out, byte) 55 # . . push args 56 ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp . . . . 0x14/disp8 . # push *(ebp+20) 57 ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp . . . . 0xc/disp8 . # push *(ebp+12) 58 # . . call 59 e8/call write-byte-hex-buffered/disp32 60 # . . discard args 61 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp 62 # write-buffered(out, Newline) 63 # . . push args 64 68/push Newline/imm32 65 ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp . . . . 0xc/disp8 . # push *(ebp+12) 66 # . . call 67 e8/call write-buffered/disp32 68 # . . discard args 69 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp 70 # flush(out) 71 # . . push args 72 ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp . . . . 0xc/disp8 . # push *(ebp+12) 73 # . . call 74 e8/call flush/disp32 75 # . . discard args 76 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp 77 # stop(ed, 1) 78 # . . push args 79 68/push 1/imm32 80 ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp . . . . 8/disp8 . # push *(ebp+8) 81 # . . call 82 e8/call stop/disp32 83 # should never get past this point 84 $error-byte:dead-end: 85 # . epilogue 86 89/copy 3/mod/direct 4/rm32/esp . . . 5/r32/ebp . . # copy ebp to esp 87 5d/pop-to-ebp 88 c3/return 89 90 # . . vim:nowrap:textwidth=0