#assembly #arm
#linux #gcc #сборка #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 указывает вызов write, если для него установлено значение # 4. Я просто пытаюсь сохранить # 8, затем распечатать сохраненный номер.
Комментарии:
1. Сначала вам нужно преобразовать число в строку (например
123
, ->"123"
).
Ответ №1:
Запись системного вызова принимает второй аргумент (r1) в качестве указателя на строку, которую вы хотите распечатать. Вы передаете ему указатель на целое число, поэтому он ничего не печатает, потому что в области памяти, которую вы ему передаете, нет символов ASCII.
Ниже вы найдете программу «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 Worldn"
Если вы хотите напечатать число, вы можете использовать функцию printf из библиотеки C. Вот так:
.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: %dn"
Наконец, если вы хотите напечатать число с помощью записи системного вызова, вы также можете реализовать функцию itoa (которая преобразует целое число в строку).
Комментарии:
1. Я искал ответ о том, как преобразовать целое число в символ в сборке ARM. Все результаты, которые я получаю, объясняют, как это сделать на C, хотя. Как бы я мог выполнить это преобразование в ARM без библиотек C?
2. Помните, что символы — это не что иное, как цифры в коде ASCII. Число 48 соответствует символу ‘0’ в ASCII. От числа 49 до ‘1’ и так далее. Следовательно, если вы хотите преобразовать целое число в символ, вы можете добавить 48 к целому числу, а затем сохранить результат как байт (а не как целое число, поскольку целые числа имеют 4 байта) в некоторой ячейке памяти. Затем, если вы отправите указатель на эту ячейку памяти на запись системного вызова, он напечатает символ.
Ответ №2:
Привет, я ценю, что это довольно старая тема, но я некоторое время ломал голову над этим и хотел бы поделиться своим решением. Может быть, это поможет кому-то на этом пути!
Я стремился печатать в цифре, не прибегая к использованию C каким-либо образом, хотя я понимаю, что простая декомпиляция tostring() — или любой другой эквивалент, существующий в C , — и посмотреть, что получилось, было бы гораздо более быстрым путем.
В основном я закончил созданием указателя на пустую строку .ascii в разделе .data и добавил к ней цифру, которую я хотел напечатать 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: " "
Самым большим недостатком этого подхода является то, что он, конечно, не обрабатывает числа длиной более одной цифры.
Мое решение для этого было намного, намного уродливее и выходит за рамки этого ответа здесь, но если у вас сильный желудок, вы можете увидеть его здесь:
Комментарии:
1. Многие ассемблеры позволяют использовать ASCII-константы в выражениях, например
#'0'
, вместо#48
. IDK, если ассемблеры ARM позволяют это, но это'0'
работает с ассемблером GNU для x86. Кроме того, вам не нужно.ascii
инициализироваться, потому что вы не читаете его перед записью.2. Приятно знать. Я проверю это, это избавило бы меня от лишних хлопот!