I am trying to get this assembly program to print out an error message when the second argument on the command line is less than 0 or larger than 12. However when using it for some reason I always get a segfault when it is in that range.
define(i_r, w19)
define(argc_r, w20)
define(argv_r, x21)
fmt: .string "%d "
err: .string "usage: a5b mm dd\n"
.balign 4
.global main
main: stp x29, x30, [sp, -16]!
mov x29, sp
mov argc_r, w0 // Copy argc
mov argv_r, x1 // Copy argv
mov i_r, 1 // Start from the second argument
cmp argc_r, 3 // Check if argc_r is 3
b.ne error // If argc_r != 3, go to error
ldr x0, [argv_r, i_r, SXTW 3] // Load the second argument string
bl atoi // Convert string to integer
cmp w0, 12 // Check if the second argument is greater than 12
bgt error // If greater than 12, go to error
cmp w0, 0 // Check if the second argument is less than 0
blt error // If less than 0, go to error
mov w1, w0 // Move the converted integer to w1
adrp x0, fmt // Load the format string
add x0, x0, :lo12:fmt
bl printf // Print the second argument
add i_r, i_r, 1 // Move to the next argument
top: ldr x1, [argv_r, i_r, SXTW 3] // Load the argument string
bl atoi // Convert string to integer
mov w1, w0 // Move the converted integer to w1
adrp x0, fmt // Load the format string
add x0, x0, :lo12:fmt
bl printf // Print the integer
add i_r, i_r, 1 // Move to the next argument
cmp i_r, argc_r // Check if all arguments are processed
b.lt top // If not, continue processing
end:
ldp x29, x30, [sp], 16
ret
error:
adrp x0, err
add x0, x0, :lo12:err
bl printf
b end
I've tried Moving the code for checking and printing the second argument (the month value) before the top label, but that still gives me the same result. I also tried changing the registers I used thinking it needed to be empty, but I still got the same result. I used gdb but it only seems that the bl atoi line is the problem, but I can't figure out specifically whats wrong with my logic. Can anyone help point me in the right direction?