- callfactorial.c Select all
/*
* An application that illustrates calling the factorial function defined elsewhere.
*/
#include <stdio.h>
#include <inttypes.h>
uint64_t factorial(unsigned n);
int main() {
for (unsigned i = 0; i < 20; i++) {
printf("factorial(%2u) = %llu\n", i, factorial(i));
}
}
- factorial.s Select all
# ----------------------------------------------------------------------
# A 64-bit recursive implementation of the function
#
# uint64_t factorial(unsigned n)
#
# implemented recursively with x86_64 and arm64 assembly code
# -----------------------------------------------------------------------
.globl _factorial
.text
#ifdef __arm64__
.align 4
#endif
_factorial:
#ifdef __x86_64__
cmp $1, %rdi # n <= 1?
jnbe L1 # if not, go do a recursive call
mov $1, %rax # otherwise return 1
ret
#endif
#ifdef __arm64__
cmp x8, #1 //# n > 1?
b.gt L1 //# if yes, go do a recursive call
mov x0, #1 //# otherwise return 1
ret
#endif
L1:
#ifdef __x86_64__
push %rdi # save n on stack (also aligns %rsp!)
dec %rdi # n-1
call _factorial # factorial(n-1), result goes in %rax
pop %rdi # restore n
imul %rdi, %rax # n * factorial(n-1), stored in %rax
ret
#endif
#ifdef __arm64__
STP X8, LR, [SP, #-16]! //# push x8 and LR(x30)
// LR is to return from subroutine
subs x8, x8, #1 //# n-1
bl _factorial //# factorial(n-1), result goes in x0
LDP X8, LR, [SP], #16 //# pop x8 and LR(x30)
mul x0, x0, x8 //# n * factorial(n-1), stored in x0
ret
#endif
(2) To compile with -g and codesign the program so as to debug in lldb under macOS.
- shell script Select all
# To compile and codesign x86_64 version
clang factorial.s callfactorial.c -g -o callfactorial_arm64 -arch x86_64 && codesign --entitlement entitlements --force -s - callfactorial_x86_64
# To compile and codesign arm64 version
clang factorial.s callfactorial.c -g -o callfactorial_arm64 -arch arm64 && codesign --entitlement entitlements --force -s - callfactorial_arm64
(3) To debug using lldb
- shell script Select all
lldb callfactorial_x86_64
# or
lldb callfactorial_arm64
# lldb debug session for arm64 - useful commands
(lldb) breakpoint set --name main --name factorial
(lldb) breakpoint list
(lldb) run
(lldb) step
(lldb) po i
(lldb) reg read x0 x8 lr pc
(lldb) reg read -f t cpsr
# lldb debug session for x86_64 - useful commands
(lldb) reg read -f d rax rdi rflags
(lldb) reg read -f t rflags
# print the address value in the stackpointer for x86_64
(lldb) p *(int **)$sp
# hint: to search lldb command history use ctrl-r
No comments:
Post a Comment