# The stack shouldn't grow into the code area. == code check-stack: # . prologue 55/push-ebp 89/<- %ebp 4/r32/esp # . save registers 50/push-eax # 89/<- %eax 4/r32/esp 3d/compare-eax-and 0x01000000/imm32 { 7f/jump-if-> break/disp8 (abort "stack overflow") } $check-stack:end: # . restore registers 58/pop-to-eax # . epilogue 89/<- %esp 5/r32/ebp 5d/pop-to-ebp c3/return show-stack-state: # . prologue 55/push-ebp 89/<- %ebp 4/r32/esp # . save registers 50/push-eax 51/push-ecx 52/push-edx # 89/<- %edx 4/r32/esp # save old cursor position (cursor-position 0) # => eax, ecx # print at top-right (set-cursor-position 0 0x70 0) (draw-int32-hex-wrapping-right-then-down-from-cursor-over-full-screen 0 %edx 0xf 0xc) # restore cursor position (set-cursor-position %eax %ecx) $show-stack-state:end: # . restore registers 5a/pop-to-edx 59/pop-to-ecx 58/pop-to-eax # . epilogue 89/<- %esp 5/r32/ebp 5d/pop-to-ebp c3/return # Helper for debugging deeply recursive calls without logs or traces. # Turn it on, insert calls in the right places, and you get a terse sense of # important parts of the call stack. A poor sophont's stack trace. debug-print: # x: (addr array byte), fg: int, bg: int # x is very short; usually a single character # . prologue 55/push-ebp 89/<- %ebp 4/r32/esp # . save registers 50/push-eax 51/push-ecx # { 81 7/subop/compare *Really-debug-print 0/imm32/false 74/jump-if-= break/disp8 (draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0 *(ebp+8) *(ebp+0xc) *(ebp+0x10)) # clear the screen and continue if we got too close to the bottom (cursor-position 0) # => eax, ecx 81 7/subop/compare %ecx 0x28/imm32 75/jump-if-!= break/disp8 (clear-screen 0) (set-cursor-position 0 0 0) } $debug-print:end: # . restore registers 59/pop-to-ecx 58/pop-to-eax # . epilogue 89/<- %esp 5/r32/ebp 5d/pop-to-ebp c3/return debug-print?: # -> _/eax: boolean # . prologue 55/push-ebp 89/<- %ebp 4/r32/esp # 8b/-> *Really-debug-print 0/r32/eax $debug-print?:end: # . epilogue 89/<- %esp 5/r32/ebp 5d/pop-to-ebp c3/return turn-on-debug-print: # . prologue 55/push-ebp 89/<- %ebp 4/r32/esp # c7 0/subop/copy *Really-debug-print 1/imm32/true $turn-on-debug-print:end: # . epilogue 89/<- %esp 5/r32/ebp 5d/pop-to-ebp c3/return turn-off-debug-print: # . prologue 55/push-ebp 89/<- %ebp 4/r32/esp # c7 0/subop/copy *Really-debug-print 0/imm32/false $turn-off-debug-print:end: # . epilogue 89/<- %esp 5/r32/ebp 5d/pop-to-ebp c3/return == data Really-debug-print: 0/imm32/false #? 1/imm32/true