using printf before and inside a loop x86-64 assembly

孤街醉人 提交于 2019-12-02 06:55:21

The easiest way to protect a register from being accessed by a subroutine is to push it. According to the ABI V calling convention printf may change any register except RBX, RBP, R12–R15. The registers you need to preserve are RAX, RDX, RSI, RDI, R8 and R11 (RCX is no longer needed), so push before the call to printf and pop them afterwards:

pushq %rax
pushq %rdx
pushq %rsi
pushq %rdi
pushq %r8
pushq %r11
movq $.LC1, %rdi
movq %rax, %rsi
movq $0, %rax
call printf
popq %r11
popq %r8
popq %rdi
popq %rsi
popq %rdx
popq %rax

Now, you can copy the block into the loop. For each printf, you have to think about what needs to be secured:

...
multInts:
pushq %rbp
movq %rsp, %rbp

#add code here for what the functions should do

pushq %rdx                  # Preserve registers
pushq %rdi
pushq %rsi
movq $.LC0, %rdi            # Format string (no further values)
movq $0, %rax               # No vector registers used
call printf                 # Call C function
popq %rsi                   # Restore registers
popq %rdi
popq %rdx

movq $0, %r8                #initialize index for array access in caller save reg

loop0:
cmpl %r8d, %edi             #compare index to size
je exit0                    #exit if equal

movslq (%rsi,%r8,4),%rax    # Load a long into RAX
movslq (%rdx,%r8,4),%r11    # Load a long into R11
imulq %r11, %rax            # RAX *= R11

pushq %rax                  # Preserve registers
pushq %rdx
pushq %rsi
pushq %rdi
pushq %r8
pushq %r11
movq $.LC1, %rdi            # Format string
movq %rax, %rsi             # Value
movq $0, %rax               # No vector registers used
call printf                 # Call C function
popq %r11                   # Restore registers
popq %r8
popq %rdi
popq %rsi
popq %rdx
popq %rax

incq %r8                    #increment index
jmp loop0

exit0:

movq %rbp, %rsp
popq %rbp
ret
...

BTW: .string "%i \n" will force printf only to process the lower 32-bit of RDI. Use .string %lli \n instead.

Assume that printf clobbers all the call-clobbered registers (What registers are preserved through a linux x86-64 function call), and use different ones for anything that needs to survive from one iteration of the loop to the next.

Look at compiler output for an example: write a version of your loop in C and compile it with -Og.

Obviously you need to move the instructions that set up the args in registers (like the format string) along with the call printf.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!