Scanf ARM 程序集
Scanf ARM Assembly
我知道有一个问题 here 但我真的不明白 OP 做了什么。我以前使用过 x86 汇编,为此你会做这样的事情:
push dword int1
push dword fmtInput
call scanf
add esp, 12
; value is now in int1
我对 ARM 的猜测是这样的
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
我确定我遗漏了一些简单的东西,但我真的很迷茫。如果 ldr 和 push 不起作用,那么还有其他操作码可以使用吗?如果其中一个是正确的,它需要什么样的输入组合?
我还尝试在 .data 部分定义一个 num: .word 0
并使用 ldr r1, =num
.data 部分中的任何内容似乎都是静态的,或者是否有其他方法将它们传递给 scanf?
如果有帮助,我正在 Qemu 的 ARMv7 处理器上使用 gcc。
--编辑--
这是我正在尝试做的事情和一些代码。该应用程序打印 hello world,获取输入,添加一个,打印新值。我的代码如下所示:
.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
输出:你好,世界。
输入:6
输出:数量:3
输出:你好,世界。
输入:d
输出:数量:2
只要我输入数字,最终输出总是3,只要我输入字符,最终输出总是2。
ldr
一定可以。这肯定编译:
ldr r0, =fmtInput
ldr r1, =num
bl scanf
.data
num: .word 0
fmtInput: .string "%d"
这就是最终对我有用的东西:
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
在这种情况下,用户输入的值最终在 r4 中。我不明白为什么 Jesters 的方式不起作用,但它每次都给出一个段错误。
@Jester 提供了完全有效的答案。我只是添加一些注释
@ 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
我知道有一个问题 here 但我真的不明白 OP 做了什么。我以前使用过 x86 汇编,为此你会做这样的事情:
push dword int1
push dword fmtInput
call scanf
add esp, 12
; value is now in int1
我对 ARM 的猜测是这样的
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
我确定我遗漏了一些简单的东西,但我真的很迷茫。如果 ldr 和 push 不起作用,那么还有其他操作码可以使用吗?如果其中一个是正确的,它需要什么样的输入组合?
我还尝试在 .data 部分定义一个 num: .word 0
并使用 ldr r1, =num
.data 部分中的任何内容似乎都是静态的,或者是否有其他方法将它们传递给 scanf?
如果有帮助,我正在 Qemu 的 ARMv7 处理器上使用 gcc。
--编辑--
这是我正在尝试做的事情和一些代码。该应用程序打印 hello world,获取输入,添加一个,打印新值。我的代码如下所示:
.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
输出:你好,世界。
输入:6
输出:数量:3
输出:你好,世界。
输入:d
输出:数量:2
只要我输入数字,最终输出总是3,只要我输入字符,最终输出总是2。
ldr
一定可以。这肯定编译:
ldr r0, =fmtInput
ldr r1, =num
bl scanf
.data
num: .word 0
fmtInput: .string "%d"
这就是最终对我有用的东西:
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
在这种情况下,用户输入的值最终在 r4 中。我不明白为什么 Jesters 的方式不起作用,但它每次都给出一个段错误。
@Jester 提供了完全有效的答案。我只是添加一些注释
@ 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