Linux 如何在ARM汇编中打印一个数字?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/17357467/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to print a number in ARM assembly?
提问by braden.groom
I am trying to print a number that I have stored. I'm not sure if I am close or way off. Any help would be appreciated though. Here is my code:
我正在尝试打印一个我存储的数字。我不确定我是近还是远。任何帮助将不胜感激。这是我的代码:
.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
It compiles and runs, but I don't see anything printed. From what I understand, I need the address of where to start printing in r1, how many bytes in r2, the file descriptor in r0, and r7 specifies the write call if it is set to #4. I am simply trying to store #8, then print the stored number.
它编译并运行,但我没有看到任何打印。据我了解,我需要在 r1 中从何处开始打印的地址、r2 中的字节数、r0 中的文件描述符以及 r7 指定写入调用(如果它设置为 #4)。我只是想存储#8,然后打印存储的数字。
采纳答案by Daniel Scocco
The syscall write takes on the second argument (r1) as a pointer to the string you want to print. You are passing it a pointer to an integer, which is why it's not printing anything, because there are no ASCII characters on the memory region you are passing to it.
系统调用 write 将第二个参数 (r1) 作为指向要打印的字符串的指针。您将一个指向整数的指针传递给它,这就是它不打印任何内容的原因,因为您传递给它的内存区域上没有 ASCII 字符。
Below you'll find a "Hello World" program using the syscall write.
您将在下面找到一个使用系统调用写入的“Hello World”程序。
.text
.global main
main:
push {r7, lr}
mov r0, #1
ldr r1, =string
mov r2, #12
mov r7, #4
svc #0
pop {r7, pc}
.data
string: .asciz "Hello World\n"
If you want to print a number you can use the printf function from the C library. Like this:
如果要打印数字,可以使用 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"
Finally, if you want to print the number with the syscall write you can also implement a itoa function (one that converts an integer to a string).
最后,如果您想使用 syscall write 打印数字,您还可以实现一个 itoa 函数(将整数转换为字符串的函数)。
回答by Tombas
Hi I appreciate that this is a pretty old thread but I've scratched my head over this for a while and would like to share my solution. Maybe it'll help someone along the way!
嗨,我很欣赏这是一个非常古老的线程,但我已经为此挠头一段时间了,想分享我的解决方案。也许它会帮助某人一路走来!
I was aiming to print to digit without recourse to using C++ in any way, though I realise that simply decompiling a tostring() - or whatever equivalent exists in C++ - and seeing what that came up with would have been a far quicker route.
我的目标是在不以任何方式使用 C++ 的情况下打印到数字,尽管我意识到简单地反编译 tostring() - 或 C++ 中存在的任何等效项 - 并查看所提出的内容会是一条更快的路线。
Basically I ended up with creating a pointer to an empty .ascii string in the section .data and added the digit that I wanted to print + 48 to it before printing off that digit.
基本上,我最终在 .data 部分创建了一个指向空 .ascii 字符串的指针,并在打印该数字之前添加了我想要打印的数字 + 48。
The +48 of course is to refer to the specific digit's ascii index number.
+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: " "
The biggest drawback of this approach is that it doesn't handle any number more than one digit long of course.
这种方法的最大缺点当然是它不处理任何超过一位数的数字。
My solution for that was much, much uglier and beyond the scope of this answer here but if you've a strong stomach you can see it here:
我对此的解决方案非常丑陋,超出了此答案的范围,但如果您的胃很强壮,您可以在这里看到它: