如何使用汇编语言从1到n打印数字?

时间:2017-08-28 05:33:40

标签: assembly raspberry-pi arm qemu

我是汇编语言的新手,我尝试使用汇编语言打印1到n个数字,而不使用C库。我使用qemu作为树莓派的模拟器。

以下是我尝试的示例代码

    .global _start
_start:
MOV R7, #3 @ Syscall read from keyboard
MOV R0, #0 @ Input stream keyboard
MOV R2, #1  @ Read 1 characters
LDR R1, =character @ Put number in R1
MOV R6,R1 @Holding value of R1 i.e. the input number 'n'
MOV R1,#0 @initialiing value 
MOV R2, #1 @counter
SWI 0

_loop:
AND R1, R1, R2 @Add one to each value of R1
B _write @print the value
SWI 0


_write:
MOV R7,#4 @ Syscall for output
MOV R0,#1 @ Output stream for R1
MOV R2,#1
CMP R1,R6 @Compare if the value is equal to 'n'
BNE _loop @if less than, then add again and print
SWI 0

end:
MOV R7,#1
SWI 0

.data
character:
.word 0

请让我知道,应该怎么做。

由于

1 个答案:

答案 0 :(得分:0)

我注意到有些事情是不对的。当调用例程(SWI)时,可以更改寄存器,因此您应该将值保存在您正在使用的寄存器中(push {r1, r2, r6, lr})并在例程(pop {r1, r2, r6, lr})之后将其恢复,期待r1和r2。 AND指令不是一个好的加法器,请使用add。在_loop:中,有一条额外的SWI 0指令。在_write:中,需要在寄存器character中有r1的地址,并且要写入的数据需要在标记为character的内存中作为可打印字符(0x00000001不是一个可打印的字符,添加0x30或十进制48将使它成为一个可打印的字符。)

我对你的程序的修改是小写的。如果您希望使用main,我会将gdb添加到顶部。我跳过/绕过输入并硬编码输入。

    .global _start
main:
_start:
@MOV R7, #3 @ Syscall read from keyboard
@MOV R0, #0 @ Input stream keyboard
@MOV R2, #1  @ Read 1 characters
@LDR R1, =character @ Put number in R1
@MOV R6,R1 @Holding value of R1 i.e. the input number 'n'
@MOV R1,#0 @initialiing value
@MOV R2, #1 @counter
@SWI 0
mov  r6, #5
mov  r1, #0
mov  r2, #1

_loop:
@AND R1, R1, R2 @Add one to each value of R1
add  r1, r1, r2
B _write @print the value
@SWI 0


_write:
push {r1, r2, r6, lr}
add  r3, r1, #48
ldr  r0, =character
str  r3, [r0]
MOV R7,#4 @ Syscall for output
MOV R0,#1 @ Output stream for R1
ldr r1, =character
MOV R2,#1
SWI 0
pop {r1, r2, r6, lr}
CMP R1,R6 @Compare if the value is equal to 'n'
BNE _loop @if less than, then add again and print

end:
MOV R7,#1
SWI 0

.data
character:
.word 0

汇编,链接和输出

as -o count2.o count2.s
ld -o count2 count2.o
./count2
12345

此外:

我没有使用QEMU,但是看https://azeria-labs.com/load-and-store-multiple-part-5/我认为问题可能是访问内存存储。试试这个,看看它是否有所作为。我还更改了pushpop指令。

    .global _start
_start:
@MOV R7, #3 @ Syscall read from keyboard
@MOV R0, #0 @ Input stream keyboard
@MOV R2, #1  @ Read 1 characters
@LDR R1, =character @ Put number in R1
@MOV R6,R1 @Holding value of R1 i.e. the input number 'n'
@MOV R1,#0 @initialiing value
@MOV R2, #1 @counter
@SWI 0
mov  r6, #5
mov  r1, #0
mov  r2, #1

_loop:
@AND R1, R1, R2 @Add one to each value of R1
add  r1, r1, r2
B _write @print the value
@SWI 0


_write:
@push {r1, r2, r6, lr}
stmdb sp!, {r1, r2, r6, lr}
add  r3, r1, #48
@ldr  r0, =character
ldr  r0, character_address
str  r3, [r0]
MOV R7,#4 @ Syscall for output
MOV R0,#1 @ Output stream for R1
@ldr r1, =character
ldr r1, character_address
MOV R2,#1
SWI 0
@pop {r1, r2, r6, lr}
ldmia sp!, {r1, r2, r6, lr}
CMP R1,R6 @Compare if the value is equal to 'n'
BNE _loop @if less than, then add again and print

end:
MOV R7,#1
SWI 0

character_address:
.word character

.data
character:
.word 0