Как адрес загрузки псевдоинструкций переводится в реальные инструкции? - PullRequest
0 голосов
/ 23 декабря 2019

Я смотрел на подобные вопросы, но они не касаются вопросов ниже.

При программировании в сборке 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
...