1 # A function which pushes n zeros on the stack. 2 # Not really useful to call manually. 3 # The Mu compiler uses it when defining arrays on the stack. 4 5 == code 6 7 #? Entry: 8 #? # . prologue 9 #? 89/<- %ebp 4/r32/esp 10 #? # 11 #? 68/push 0xfcfdfeff/imm32 12 #? b8/copy-to-eax 0x34353637/imm32 13 #? $dump-stack0: 14 #? (push-n-zero-bytes 4) 15 #? 68/push 0x20/imm32 16 #? $dump-stack9: 17 #? b8/copy-to-eax 1/imm32/exit 18 #? cd/syscall 0x80/imm8 19 20 # This is not a regular function, so it won't be idiomatic. 21 # Registers must be properly restored. 22 # Registers can be spilled, but that modifies the stack and needs to be 23 # cleaned up. 24 25 # Overhead: 26 # 62 + n*6 instructions to push n bytes. 27 # If we just emitted code to push n zeroes, it would be: 28 # 5 bytes for 4 zero bytes, so 1.25 bytes per zero. And that's not even 29 # instructions. 30 # But on the other hand it would destroy the instruction cache, where this 31 # approach requires 15 instructions, fixed. 32 33 # n must be positive 34 push-n-zero-bytes: # n: int 35 $push-n-zero-bytes:prologue: 36 89/<- *Push-n-zero-bytes-ebp 5/r32/ebp # spill ebp without affecting stack 37 89/<- %ebp 4/r32/esp 38 $push-n-zero-bytes:copy-ra: 39 # -- esp = ebp 40 50/push-eax 41 # -- esp+8 = ebp+4 42 # -- esp+4 = ebp 43 8b/-> *(esp+4) 0/r32/eax 44 2b/subtract *(ebp+4) 4/r32/esp 45 # -- esp+4+n = ebp 46 89/<- *(esp+4) 0/r32/eax 47 58/pop-to-eax 48 # -- esp+n = ebp 49 $push-n-zero-bytes:bulk-cleaning: 50 89/<- *Push-n-zero-bytes-esp 4/r32/esp 51 81 0/subop/add *Push-n-zero-bytes-esp 4/imm32 52 81 0/subop/add *(ebp+4) 4/imm32 53 (zero-out *Push-n-zero-bytes-esp *(ebp+4)) # n+4 54 $push-n-zero-bytes:epilogue: 55 8b/-> *Push-n-zero-bytes-ebp 5/r32/ebp # restore spill 56 c3/return 57 58 == data 59 Push-n-zero-bytes-ebp: # (addr int) 60 0/imm32 61 Push-n-zero-bytes-esp: # (addr int) 62 0/imm32