Все комментарии по вашему вопросу актуальны, но никто еще не опубликовал фактический ответ , так что вот так!
По своей природе строки имеют переменную длину.По этой причине они почти всегда хранятся в памяти и передаются с помощью указателя на первый символ.Также по соглашению (по крайней мере, в мире C, и вы взаимодействуете с библиотеками C в своем коде), длина строки нигде не сохраняется, а конец строки вместо этого отмечается нулевым байтом.
На самом деле вы используете строки в обычном правильном порядке в нескольких местах вашего кода - например, когда вы получаете адрес addr_prompt
для передачи в качестве первого аргумента printf
.Когда вы используете инструкцию
ldr r2, addr_string_arg
, вы загружаете адрес первого символа строкового аргумента в r2
, и было бы стандартной практикой использовать этот адрес для представления строки.Когда вы впоследствии пишете
ldr r2, [r2]
, вы фактически разыменовываете указатель и загружаете четыре байта (32 бита), начиная с этого адреса, в r2
.r2
не содержит строку, только первые четыре байта;и действительно, эти байты могут даже не быть в том же порядке, в каком они были в памяти, в зависимости от порядкового номера вашей системы.
Обратите внимание, что вы должны выделить достаточно места для хранениясамая длинная строка, которую вы когда-либо ожидали, и в данный момент вы этого не делаете (string_read
- это всего 4 байта, что с символом завершения допускает трехсимвольную строку).Разрешение строке переполнять ее буфер приводит к неопределенному поведению.
Кроме того, когда вы загружаете произвольные константы (включая адреса) в регистры, псевдоинструкция LDR
- это то, что вам нужно - издесь используется знак равенства перед вторым аргументом.Это может собирать в несколько инструкций, в зависимости от загружаемой константы;для соседних адресов он часто реализуется как относящийся к ПК ADD
, но вам не нужно об этом беспокоиться, когда вы его используете.Например,
ldr r2, =string_read
устраняет необходимость в addr_string_arg
.