Регистр сборки ARM-Link не возвращает основную подпрограмму

#assembly #arm #cortex-m #keil

#сборка #arm #cortex-m #keil

Вопрос:

Я хотел бы получить десятичный ввод от пользователя из Termite и сохранить ввод в регистре R7. Мой код работает нормально, я протестировал и обнаружил правильный вывод на R7. Но когда я запускаю, после завершения моего q4convert, я хочу, чтобы он вернул main, как и должно быть. Однако, когда строка

take BL InChar

выполняется, регистр ссылок сохраняет эту строку и продолжает возвращать эту строку после того, как q4convert.s завершается следующим утверждением.

             POP     {R1,R4,R5,R6}
            BX      LR
  

Мой основной

 ;LABEL      DIRECTIVE       VALUE       COMMENT         
            AREA        sdata, DATA, READONLY
            THUMB
EnterMSG    DCB         0x0A
            DCB         "Enter the number of food parcels. Expected Input format ends with '*' i.e. = 520*,100*,15*"
            DCB         0x0D
            DCB         0x04
            
            AREA    main,   READONLY,   CODE
            THUMB
            EXTERN  OutStr
            EXTERN  q4convert
            EXPORT __main           

__main      PROC
            LDR     R5,=EnterMSG        
            BL      OutStr          
            BL      q4convert
done        B       done            
            ENDP
  

Моя подпрограмма, которая принимает вводную цифру за цифрой и сохраняет ее в R7.

             AREA    convert, READONLY, CODE
            THUMB
            EXPORT  q4convert           ; make available to other programs
            EXTERN  InChar
                
q4convert   PROC
            PUSH    {R1,R4,R5,R6}
take        BL      InChar              ;Get n
            CMP     R5,#0x2A            ;Example input format ends with * whose asci code is 0x2A
            STRBNE  R5,[R6],#-1         ;Store digits as descending order. Dont store ASCII OF '*'
            ADDNE   R4,#1               ;R4 Counts the digits. No addition for '*'
            BNE     take
            SUB     R4,#1               ;Sets R4 to Digit-1. This will be used to reach the correct address with offset. 
            MOV32   R6,#0x20000500
            MOV     R10,#10
point           
            LDRB    R1,[R6],#-1         ;Point the correct digit starting from most significant.
            SUB     R1,#48              ;R1 has the digit.  
            PUSH    {R4}            
loop        
            MUL     R1,R10
            SUBS    R4,#1
            BNE     loop            
            POP     {R4}
            SUBS    R4,#1
            ADD     R7,R1               ;R7 is the our input number.    
            CMP     R4,#0
            BNE     point
            BEQ     final
final       
            LDRB    R1,[R6]
            SUB     R1,#48
            ADD     R7,R1               ;Adds least significant digit.
            POP     {R1,R4,R5,R6}
            BX      LR
            ENDP
  

Мои файлы inChar.s, OutStr.s — это предварительно записанные файлы TexasInstrument, в них нет ничего плохого.
OutStr печатает строку, расположенную в памяти. Начальный адрес строки передается в R5.
inChar хранит символы в R5.

Моя плата — Texas Instruments EK-TM4C123GXL

Я буду рад, если кто-нибудь сможет мне помочь. Спасибо

Комментарии:

1. Существует только один регистр ссылок. Вам необходимо сохранить этот регистр q4convert перед вызовом каких-либо дополнительных функций. Самое простое решение — изменить push {r1, r4, r5, r6} на push {r1, r4, r5, r5, lr} и pop {r1, r4, r5, r6} на pop {r1, r4, r5, r6, pc} .

2. Я понял, почему мы нажимаем lr, но вы вытащили pc вместо LR. Почему это?

3. PC — это программный счетчик, вставляя старый LR в PC, мы возвращаемся из функции. С ARMv6-M (который, похоже, так и есть; вы не сказали), вы не можете LR только всплывать PC . Поскольку вы все равно хотите вернуться, это хорошее решение.

4. Да, можно запустить LR на ARM-Cortex M4 (который использует ARMv7-M). Однако действительно ли это необходимо? pop {r1, r4, r5, r6, pc} делает то же самое, pop {r1, r4, r5, r6, lr}; bx lr что и в одной инструкции.

5. выскакивает lr, затем bx lr возвращается к полноразмерному arm, и для armv4t вам нужно сделать это таким образом, если вы хотите поддерживать взаимодействие с большим пальцем, armv5t и более поздние версии вы можете открыть pc, и он переключит режимы. armv7-m вы можете открыть либо lr, либо pc, но не оба. Если нажать lr для вложенности, то он сохраняет инструкцию на pop pc