Выполнение не выходит из цикла в ARM - PullRequest
1 голос
/ 22 октября 2019

Я хочу напечатать на языке ассемблера ARM заданное число в десятичном и шестнадцатеричном виде. Я делаю функцию, которая делает преобразование и печать. Пока что конверсия работает, но печать совсем не работает.

Он печатает только символ за раз, и это совсем не то, что я хочу, я хочу специальный формат вывода, такой, чтобы у меня были 0x и 8 цифр.

Я написал функцию printf , используя данную функцию, которая называется _writec , которая работает, но одновременно печатает только символ. Поэтому я писал цикл до тех пор, пока не получил функцию конца строки, но здесь, похоже, это не волнует.

Я пошагово следил за выполнением, используя gdb, и он внезапно завершился сбоем, так как не появлялсяпричина. Когда r0 содержит 0, он должен перейти к .end в соответствии с моим beq , но это не так.

Код 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, он выводит результат, но не в нужном формате. Я получил только шестнадцатеричное значение.

...