首页 > 解决方案 > 在 ARM 中执行不会跳出循环

问题描述

我想用 ARM 汇编语言以十六进制打印给定的十进制数字。我正在做转换和打印的功能。到目前为止,转换工作,但打印根本没有。

它一次只打印一个字符,这根本不是我想要的,我想要一种特殊的输出格式,这样我就有 0x 和 8 位数字。

我使用我拥有的给定函数编写了一个函数printf,称为_writec,它正在工作,但一次只打印一个字符。所以我写了一个循环,直到我得到字符串函数的结尾,但在这里似乎它并不关心。

我已经使用 gdb 一步一步地执行了,它突然崩溃了,没有出现任何原因。当 r0 包含 0 时,它应该根据我的beq转到.end但它没有。

ARM代码:

.global _print_hex
_print_hex:

push {lr}
@According to .c algorithm : r0 = dec; r1 = quotient; 
@ r2 = temp; r3 = i ; r4 = j 

mov fp, sp
sub sp, sp, #100 @ 100 times size of char
mov r1, r0
mov r3, #0

_while:
   cmp r1, #0
   bne _computing

   ldr r0, =.hex_0x
   bl _printf

   mov r4, #8
_for:
   cmp r4, #0
   bge _printing

   ldr r0, =.endline
   bl _printf

   mov sp, fp
   pop {pc}

_computing:
   and r2, r1, #0xF
   cmp r2, #10
   blt .temp_less_10
   add r2, #7
   .temp_less_10:
   add r2, #48
   strb r2, [sp, r3]
   add r3, #1
   lsr r1, #4
   b _while 

_printing:
   ldrb r0, [sp,r4]
   bl _writec
   sub r4, #1
   b _for

_printf:
   push {r0, r1, r2, r3, lr}
   mov r1, r0
   mov r2, #0
.loop:
   ldrb r0, [r1,r2]
   cmp r0, #0
   beq .end
   bl _writec
   add r2, #1
    b .loop

.end:
   pop {r0, r1, r2, r3, lr}
   bx lr

.hex_0x:
   .asciz "0x"
   .align 4

.endline:
   .asciz "\n"
   .align 4

C代码(我试图翻译):

 void dec_to_hex(int dec){
       int quotient, i, temp;
       char hex[100];
       quotient = dec;
       i = 0;

    while (quotient != 0){
        temp = quotient % 16;
        if (temp < 10){
            temp += 48; // it goes in the ascii table between 48 and 57 that correspond to [0..9]
        } else {
            temp += 55; //it goes in the first cap letters from 65 to 70 [A..F]
        }
        hex[i]=(char)temp;
        i++;
        quotient /= 16;
    }
    printf("0x");
    for(int j=i; j>=0; j--){
        printf("%c", hex[j]);
    }
    printf("\n");
}

这是 _writec 的代码:

/*
 * Sends a character to the terminal through UART0
 * The character is given in r0.
 * IF the TX FIFO is full, this function awaits
 * until there is room to send the given character.
*/
    .align 2
.global _writec
    .type _writec,%function
    .func _writec,_writec
_writec:
    push {r0,r1,r2,r3,lr}
    mov r1, r0
    mov r3, #1
    lsl r3, #5      // TXFF = (1<<5)

    ldr r0,[pc]
    b .TXWAIT
    .word UART0
.TXWAIT:
    ldr r2, [r0,#0x18]      // flags at offset 0x18
    and r2, r2, r3      // TX FIFO Full set, so wait
    cmp r2,#0
    bne .TXWAIT
    strb r1, [r0,#0x00]      // TX at offset 0x00
    pop {r0,r1,r2,r3,pc}
    .size   _writec, .-_writec
    .endfunc 

因此,在 ARM 中,调试时它在我第一次调用时崩溃了_printf,当我评论所有对它的调用时,_printf它确实打印了结果,但不是所需的格式。我只得到了十六进制值。

标签: cassemblyarmqemu

解决方案


推荐阅读