0

I am trying to print a string char by char, with this ARM32 code:

.global main
.type main%function

@ r0 = asciz c
@ r1 = singlechar
@ r2 = string
@ r3 = offset

main:
        mov r3,#0    // initialize offset
        ldr r0,=single_c
        ldr r2,=string
        push {ip,lr}    // save the lr
loop:
        ldrb r1,[r2,r3]    // load 1 byte of the address string+offset
        cmp r1,#0    // if the char is the null char
        beq end    // then go to the end
        bl printf    // else printf("%c",r1)
        add r3,#1    // increase offset
        b loop    // repeat the loop
end:
        pop {ip,lr}    // restore lr
        bx lr    // return

string:
        .asciz "Test\n"

single_c:
        .asciz "%c\n"
                                  

I really don't get what am I doing wrong, since if I execute it, I get this:

$ /a.out
T
Segmentation Fault

So it only prints the first letter.

EDIT: I added a push {r0,r1,r2,r3} before the printf call and a pop {r0,r1,r2,r3} after the printf call, and now it works... but my question is: does printf ALWAYS modify the first four register?

Mnkisd
  • 504
  • 2
  • 12
  • 2
    What registers does printf use? – Martin James Sep 11 '20 at 17:56
  • @MartinJames r0 for the message_format, and r1 and so on for the arguments of printf. In this case there's only one argument so only r0 and r1 are being used. – Mnkisd Sep 11 '20 at 17:58
  • 3
    And which registers is printf allowed to *modify*? Return value in r0, and it will also step on the other call-clobbered registers in the ARM calling convention. – Peter Cordes Sep 11 '20 at 18:03
  • thanks @PeterCordes , I pushed r0,r1,r2,r3 and now it works. My question is: does printf ALWAYS modify these registers from r0 to r3? – Mnkisd Sep 11 '20 at 18:12
  • 2
    Printf is a pretty complicated function; I'd assume every sane implementation of it would use all the call-clobbered registers for something, even in the simplest case of a format string with no conversions. It has to add the string to the stdout I/O buffer and/or make a write system call, after scanning the format string. Since the calling convention allows it to use those registers, there's no reason to think it ever might not. But anyway, you always have to *assume* it has trashed them because the calling convention allows it to. – Peter Cordes Sep 11 '20 at 18:27
  • 2
    @Peter Cordes: Not sure if this is how things work on Stackoverflow, but I would gladly spend some time crafting an answer explaining how exactly to debug the offending program in the user's environment, using the comments that were made above. A couple of the user's other questions could probably have been self-answered with a minimal knowledge on how to debug a Aarch32 program on a Aarch64 system. My understanding is that this would require this question to be-reopened for some time though. – Frant Sep 11 '20 at 19:11
  • 2
    @Frant: Feel free to write a separate self-answered Q&A about that. A nice canonical about *how* to debug asm would be a useful thing to be able to link in *lots* of situations, especially if the Q title reflects what it's truly about. Tacking it on to an answer to this boring duplicate of a problem that many people have repeated many times (including for other ISAs) would bury it where future readers are unlikely to find it. A significant fraction of asm questions wouldn't need to be posted at all if people knew how to debug, but writing long how-to-debug answers to every one doesn't scale. – Peter Cordes Sep 11 '20 at 19:17
  • @Peter Cordes: Ok, thank you for the feedback. – Frant Sep 11 '20 at 19:20
  • 2
    @Mnkisd not really relevant what printf modifies, printf is massive with all the nested functions it can call depending, any one of those can modify the volatile registers. What matters is the calling convention says those registers are fair game the callee can modify them so you cannot have any expectation that they will remain. So if you want to mix with compiled code you need to follow the calling convention for that compiler for that target. – old_timer Sep 11 '20 at 22:46

0 Answers0