如何解决如何使用 write 系统调用打印整数?
这是一个简单的项目,它从系统时钟创建一个随机数字。它需要一个数字,将其转换为一个数字,然后加上 48,以便在 ASCII 表中匹配。我的问题是它不打印任何东西。据我所知,它必须是一个字符串才能考虑打印。有没有办法可以“投射”它?就像是的,我知道,它是一个整数,但假装它在 ascii 表上?这是我的代码供参考。除了“prnt_clock”,一切正常。最后一件事,我不能使用任何 C 代码/函数,所以不,我不能使用 printf。
.global rand
.equ STDOUT,1
.equ WRITE,4
rand:
PUSH {LR}
BL get_clock
LDR R1,=time
ADD R1,R1,#5
LDRB R0,[R1]
BL num_to_digit
ADD R0,R0,#48
MOV R1,R0
BL prnt_clock
B rand_leave
get_clock:
MOV R7,#78 @ Get time of day
LDR R0,=time @ address of holder for time_t
MOV R1,#0 @ time zone not needed
SWI 0
MOV PC,LR
// Assumes the number is in R0
num_to_digit:
CMP R0,#9 @ Compare num to 9
SUBGT R0,#10 @ If greater than,substract 10
BGT num_to_digit @ Repeat until its eq or lower than 9
MOV PC,LR @ Comeback to main
prnt_clock:
MOV R0,#STDOUT @ Print to terminal
MOV R2,#1 @ Print only the digit
MOV R7,#WRITE @ Write Syscall
@MOV R3,#0 @ Create a counter
SWI 0
rand_leave:
POP {LR}
MOV PC,LR
.data
time: .space 9
解决方法
通常,您使用 printf 或其他库来打印整数。
如果您正在寻找独立程序,请使用编译器编译 C 以进行汇编输出:
/*
r3 = magic division number
r2 = division
r0 = integer to be converted
*/
.syntax unified
.equ division,0x66666667 // 1717986919; (2 ^ 34 + 6) / 10
.section .text
.global _start
_start:
push {ip}
mov r1,#0x0a // 10; newline
push {r1}
mov r7,#0x04 // write syscall
/*
If your architecture is ARMv7 (or above).
movw r3,#:lower16:division // 26215
movt r3,#:upper16:division // 26214
*/
ldr r3,=division
mov r0,#(0x01 << 0x1e) // replace this
_division:
smmul r1,r0,r3
asr r2,r1,#0x02
_modulo:
add r1,r2,lsr #0x1f // 31
add r1,lsl #0x02
sub r0,lsl #0x01
_string:
add r0,#0x30 // 48; '0'
push {r0}
_shift:
mov r0,r2
cmp r0,#0x00
bne _division
_write:
mov r1,sp
ldr r3,[r1]
cmp r3,#0x00
beq _end
mov r0,#0x01 // stdout file descriptor
pop {ip}
mov r2,#0x01 // length
swi 0x00 // execute syscall
bne _write
_end:
pop {ip}
mov r7,#0x01 // exit syscall
mov r0,#0x00 // exit status
swi 0x00 // execute syscall
Github(更新更多):https://raw.githubusercontent.com/GrpeApple/Assembly/test/ARM/src/arm/int2str.S
如果您希望这是您的依赖项:https://raw.githubusercontent.com/GrpeApple/Assembly/test/ARM/src/deps/int2str.S(使用寄存器 r0-r2
)
请参阅 Why does GCC use multiplication by a strange number in implementing integer division? 以了解比实际除法指令更有效地除以 10 的 smmul
/ asr
技巧。
您使用模和除法分别获得最后一个整数和倒数第二个整数。您使用除法检查直到为零。
它添加了 '0' 的 ascii 值。 我也包含在 ARMv7 的评论中。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。