# Copyright 2022 Gabriel Jensen. # This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. # If a copy of the MPL was not distributed with this file, You can obtain one at https://mozilla.org/MPL/2.0/. .globl zap_memfor zap_memfor: # Address of the current element: #define addr %rbx # Address of the element after the last input element: #define afterbuf %r12 # Size of each input element: #define sz %r13 # Address of the function: #define fn %r14 # We're gonna use callee-saved registers for storing values so they don't get overwritten with each function call. # Push the callee-saved registers: pushq addr pushq afterbuf pushq sz pushq fn # Move registers into place: movq %rdi,addr movq %rsi,sz movq %rdx,afterbuf movq %rcx,fn # Get the one-past-the-end address: imulq sz,afterbuf # afterbuf *= sz // Calculate the array size in bytes (sz * num). We're using signed multiply because the equivalent using the unsigned instruction would use more instructions. addq addr,afterbuf # afterbuf += addr # Iterate through the array: .loop: # Check if we have reached the one-past-the-end address: cmpq addr,afterbuf # if (addr == afterbuf) je .done # goto done # Call the provided function: movq addr,%rdi # // Provide the current address to the function. call *fn # fn(addr) // We don't need to save any registers for this as we only use callee-saved registers. # Continue to the next element: addq sz,addr # addr += sz jmp .loop # goto loop # Finish: .done: # Restore the callee-saved registers: popq fn popq sz popq afterbuf popq addr ret # return