#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