2013-06-28 41 views
5

我想打印一个我已经存储的数字。我不确定我是否接近或离开。任何帮助将不胜感激。这里是我的代码:如何在ARM程序集中打印数字?

.data 
.balign 4 
a: .word 4 

.text 
.global main 
main: 
     ldr r0, addr_of_a 
     mov r1, #8 
     str r1, [r0] 
write: 
     mov r0, #1 
     ldr r1, addr_of_a 
     mov r2, #4 
     mov r7, #4 
     swi #0 
     bx lr 

addr_of_a: .word a 

它编译和运行,但我没有看到任何打印。据我所知,我需要在r1中开始打印的地址,r2中有多少个字节,r0中的文件描述符以及r7是否指定写入调用(如果它设置为#4)。我只是试图存储#8,然后打印存储的号码。

+3

您需要将数字转换为字符串(例如'首先是123' - >'“123”')。 – Michael

回答

4

系统调用写入需要第二个参数(r1)指向要打印的字符串的指针。你传给它一个指向一个整数的指针。这就是为什么它不会打印任何内容,因为在传递给它的内存区域上没有ASCII字符。

下面你会发现一个使用系统调用写入的“Hello World”程序。

.text 
.global main 
main: 
     push {r7, lr} 

     mov r0, #1 
     ldr r1, =string 
     mov r2, #20 
     mov r7, #4 
     svC#0 

     pop {r7, pc} 

.data 
string: .asciz "Hello World\n" 

如果要打印数字,可以使用C库中的printf函数。就像这样:

.text 
.global main 
.extern printf 
main: 
     push {ip, lr} 

     ldr r0, =string 
     mov r1, #1024 
     bl printf 

     pop {ip, pc} 

.data 
string: .asciz "The number is: %d\n" 

最后,如果你想与系统调用写你也可以实现itoa函数(一个整数转换为字符串)打印数量。

+1

我已经搜索了如何将整数转换为ARM程序集中的字符的答案。我得到的所有结果都解释了如何在C中做到这一点。如果没有C库在ARM中进行这种转换,我该如何去做? –

+0

请记住,字符只不过是ASCII码中的数字。数字48对应ASCII中的字符'0'。数字49到'1'等等。因此,如果要将整数转换为char,则可以将48添加到整数,然后将结果作为一个字节(而不是整数,因为ints有4个字节)存储在某个内存位置。然后,如果您将该内存位置的指针发送到系统调用写入,它将打印该字符。 –

3

嗨,我明白这是一个非常古老的线程,但我已经摸了一会儿,并想分享我的解决方案。也许它会帮助一路上的人!我只是意识到打印到数字而不以任何方式使用C++,但我意识到只是简单地反编译一个tostring() - 或者C++中存在的任何等价物 - 并且看到它会出现什么样的结果更快的路线。

基本上,我最终创建了一个指向部分.data中的空白.ascii字符串的指针,并在打印该数字之前添加了我想要打印的数字+ 48。

+48当然是指具体数字的ascii索引号。

.global _start 

_start: 
MOV R8, #8 
ADD R8, R8, #48 

LDR R9, =num 
STR R8, [R9] 

MOV R0, #1 
LDR R1, =num 
MOV R2, #1 
MOV R7, #4 
SWI 0 

.data 

num: 
.ascii: " " 

这种方法的最大缺点是,它当然不能处理超过一位数的任何数字。

我该解决方案是非常非常丑陋超越这个答案,这里的范围,但如果你已经强健脾胃,你可以看到它here

+0

许多汇编器让你在表达式中使用ASCII常量,例如'#'0''而不是'#48'。如果ARM汇编程序允许的话,IDK可以使用,但它可以与x86的GNU汇编程序一起使用。另外,你不需要'.ascii'来初始化,因为你在写之前不会读它。 –

+0

很高兴知道。我会检查一下,会救了我一些麻烦! – Tombas