# A function which pushes n zeros on the stack. # Really only intended to be called from code generated by mu.subx (for array # vars on the stack). == code #? Entry: #? # . prologue #? 89/<- %ebp 4/r32/esp #? # #? 68/push 0xfcfdfeff/imm32 #? b8/copy-to-eax 0x34353637/imm32 #? $dump-stack0: #? (push-n-zero-bytes 4) #? 68/push 0x20/imm32 #? $dump-stack9: #? b8/copy-to-eax 1/imm32/exit #? cd/syscall 0x80/imm8 # This is not a regular function, so it won't be idiomatic. # Registers must be properly restored. # Registers can be spilled, but that modifies the stack and needs to be # cleaned up. # Overhead: # 62 + n*6 instructions to push n bytes. # If we just emitted code to push n zeroes, it would be: # 5 bytes for 4 zero bytes, so 1.25 bytes per zero. And that's not even # instructions. # But on the other hand it would destroy the instruction cache, where this # approach requires 15 instructions, fixed. # n must be positive push-n-zero-bytes: # n: int $push-n-zero-bytes:prologue: 89/<- *Push-n-zero-bytes-ebp 5/r32/ebp # spill ebp without affecting stack 89/<- %ebp 4/r32/esp $push-n-zero-bytes:copy-ra: # -- esp = ebp 89/<- *Push-n-zero-bytes-eax 0/r32/eax 8b/-> *esp 0/r32/eax 2b/subtract *(ebp+4) 4/r32/esp # -- esp+n = ebp 89/<- *esp 0/r32/eax 8b/-> *Push-n-zero-bytes-eax 0/r32/eax $push-n-zero-bytes:bulk-cleaning: 89/<- *Push-n-zero-bytes-esp 4/r32/esp 81 0/subop/add *Push-n-zero-bytes-esp 4/imm32 81 0/subop/add *(ebp+4) 4/imm32 (zero-out *Push-n-zero-bytes-esp *(ebp+4)) # n+4 $push-n-zero-bytes:epilogue: 8b/-> *Push-n-zero-bytes-ebp 5/r32/ebp # restore spill c3/return == data Push-n-zero-bytes-ebp: # (addr int) 0/imm32 Push-n-zero-bytes-esp: # (addr int) 0/imm32 Push-n-zero-bytes-eax: 0/imm32