Я смотрел на подобные вопросы, но они не касаются вопросов ниже.
При программировании в сборке MIPS, существует псевдоинструкция под названием адрес загрузки (la) .
Я пришел из языков более высокого уровня, так что потерпите меня, если я еще не спустился в кроличью нору.
Посмотрев, что означает эта псевдоинструкция, я обнаружил в MIPS wiki следующее:
la $a0,address
переводится в
lui $at, 4097 (0x1001 → upper 16 bits of $at).
ori $a0,$at,disp
, где непосредственный (disp) - количество байтов между первыми даннымиместоположение (всегда 0x 1001 0000) и адрес первого байта в строке.
В остальном Я нашел другое расширение:
# la $t, A
lui $t, A_hi
ori $t, $t, A_lo
Принципиально,Я думаю, что я понимаю последний код. Мы хотим поместить 32-битный адрес в регистр $ t, используя инструкцию, но для инструкций типа I мы можем разместить в инструкции только 16-битные адреса, поэтому нам нужны две инструкции, поскольку мы не можем вписать 32 бита в одну. инструкция.
Как этот второй перевод относится к первому приведенному выше?
Кроме того, в качестве более практического вопроса, скажем, у меня есть следующая программа сборки:
.data
prompt1: .asciiz "How old are you?"
.text
main:
la $a0, prompt1
Как мне заменить инструкцию la
настоящими инструкциями?
Примечание: я вижу, что симулятор переводит на:
lui $1, 4097
ori $4, $1, 0
Но в этом случае он использует регистр $ 1, который является регистром, зарезервированным для ассемблера. Я бы не смог этим воспользоваться, если бы сам написал инструкцию, верно? Кроме того, lui
устанавливает верхние биты на 1001. Я знаю, что статические данные начинаются с 0x10010000, поэтому там будет начинаться строка с меткой prompt1
. Но (и это та часть, в которой, возможно, я не понял, как именно контролирует программист в сборке), если бы у меня был другой ярлык prompt2 сразу после prompt1, я должен был бы точно знать, сколько байтов приходитпосле первой метки, чтобы правильно выбрать непосредственную константу для вставки ori
?
РЕДАКТИРОВАТЬ: Для того, чтобы контекстуализировать то, что я делаю, вот некоторый код (кстати, это буквальнопервую программу сборки я пишу сам):
.data
prompt1: .asciiz "How old are you?"
response1: .asciiz "You are "
.text
main:
ori $v0, $zero, 4 # syscall number for printing a string
lui $a0, 4097 # load the first address of static data segment
syscall # prompt the user
ori $v0, $zero, 5 # syscall number for reading an integer
syscall # read integer
or $t0, $v0, $zero # save read integer to temp register
lui $a0, 4097 # load the first address of static data segment
ori $a0, $a0, 16 # response1 starts at byte 16 from start of static data segment
ori $v0, $zero, 4 # syscall number for printing a string; response1
syscall # print response1
ori $v0, $zero, 1 # syscall number for printing an integer
or $a0, $zero, $t0 # place the age the user typed in into $a0 for syscall
syscall # print the age the user typed in
ori $v0, $zero, 10 # syscall number for exiting
syscall