0
votes

I know there's a question here but I really don't understand what the OP did. I've used x86 assembly before and for that you'd do something like this:

push dword int1
push dword fmtInput
call scanf
add esp, 12
; value is now in int1

my guess for ARM is something like this

ldr r0, fmtInput
push r1 @ says this is too complex, tried `ldr r1` but that also failed saying that ldr needed more inputs
bl scanf
@ I'm assuming the value is now in r1

I'm sure I'm missing something simple but I'm really very lost. If ldr and push don't work then is there some other opcode to use? If one of those is correct, what combination of inputs does it need?

I also tried defining a num: .word 0 in the .data section and using ldr r1, =num anything in the .data section seems to be static or is there another way to pass them to scanf?

I'm using gcc on an ARMv7 processor in Qemu if that helps.

--EDIT--

Here's what I'm trying to do and some code. The app prints hello world, gets input, adds one, prints the new value. My code looks like this:

.text
.align 4
.global main
main:
    @ keep stack 8-byte aligned
    push {ip, lr}

    @ print message
    ldr r0, =message
    bl printf

    @ scanf for number
    ldr r0, =fmtInt
    ldr r1, =num
    bl scanf

    @ add 2 to input and store in r3
    @ldr r1, =num
    mov r2, #2
    add r3, r2, r1

    @ print new value
    ldr r0, =textOut
    mov r1, r3
    bl printf

    @ return 0
    mov r0, #0

    @ reverse align
    pop {ip, pc}

@ vars and stuff
.data
message:    .asciz "Hello, world.\n"
fmtInt:     .string "%d"
textOut:    .asciz "num: %d\n"
num:        .word 1

Output: Hello, world.

Input: 6

Output: num: 3


Outout: Hello, world.

Input: d

Output: num: 2

the final output is always 3 so long as I input a number and 2 so long as I input characters.

3
i don't know what you are trying to do and i've forgotten most of arm assembly, but i still found a problem. that is the first few parameters are passed through registers not by stack. - Jason Hu
Write a simple function in C that calls scanf, compile with gcc -S, then inspect the generated assembler source and use it as a template for your own code. - Paul R
Technically it depends entirely on whatever library implementation you're linking with, since it's possible for that to use whatever mental calling convention it likes, although it's infinitely more likely to use the standard one. - Notlikethat
I'm writing an extremely simple app using gcc to link. Looking at the output from a c program helps but it does a quite a few things I really just don't understand. I suppose there could be quite a few different ways to do this but I'm really only interested in one -- I'm not asking a hypothetical question. - dlkulp
As I often find myself saying, a little blip as to what I can do to improve this question rather than just downvoting it would be appreciated. If I need to add something to make it more clear or clarify something, let me know and I'll see what I can do! - dlkulp

3 Answers

5
votes

ldr should by all means work. This certainly compiles:

ldr r0, =fmtInput
ldr r1, =num
bl scanf

.data
num: .word 0
fmtInput: .string "%d"
4
votes

This is what ended up working for me:

sub     sp, sp, #4

@ Call scanf and store value in r4
ldr     r0, addrInp
mov     r1, sp
bl      scanf
ldr     r4, [sp]

add     sp, sp, #4

The value the user inputs ends up in r4 in this case. I don't understand why Jesters way didn't work but it just gave a segfault every time.

1
votes

@Jester provided totally valid answer. I'll just add a few notes

@ scanf for number
ldr r0, =fmtInt
ldr r1, =num
bl scanf
@ scanf puts write value into addr provided by r1 (eg addr of 'num')
@ scanf does not put read value into register!
@ r0, r1, r2, r3 are volatile registers and might be changed by scanf

@ add 2 to input and store in r3
ldr r1, =num     <--- load addr of 'num' into r1
ldr r1, [r1]     <--- read value from 'num' addr into r1.
mov r2, #2
add r3, r2, r1   <--- r3 = scanf-ed value + 2
...

.data
message:    .asciz "Hello, world.\n"

.align 2         <--- align address of 'num' by 4 (2^2)
num:        .word 1