How do I get the atoi function to work in Assembly?

41 views Asked by At

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?

0

There are 0 answers