Почему незаконно использовать la с косвенным регистром операнда в MIPS?

Я получил домашнее задание с оценкой 8/10 баллов, потому что я «незаконно» использовал адрес загрузки, чтобы установить регистр назначения в соответствии с содержимым регистра s. Ниже показана рассматриваемая операция:

la  $t1, ($t0)  

$ t0 содержал шестнадцатеричное слово, которое мы должны были преобразовать в десятичное, но это не важно. MARS (симулятор MIPS, который мы используем для класса ассемблера) предлагает это, когда вы набираете la:

"la $ t1, ($ t2) Адрес загрузки: установить $ t1 в содержимое $ t2"

Она только что закончила говорить всему классу (который все делал одно и то же), что это незаконно, а затем я показал ей, как МАРС предложил эту инструкцию. Программа работает нормально и включена сюда:

Итак, мой длинный вопрос: действительно ли это незаконно, или она просто не знает, о чем говорит?

# Project/Class Description:
# Formats an IP address from a value in memory 
# using shifts and AND operations.
#
.data
inHex:  .asciiz "IP Address in Hex: "
header: .asciiz "\nFormatted IP Address: "

IPinHex: .word 0x58dc45c3
dot:    .asciiz "."

.text globl

main:
li  $v0, 4      # print hex header
la  $a0, inHex
syscall

la  $t0, IPinHex
li  $v0, 34     # print hex number
lw  $a0, ($t0)
syscall

li  $v0, 4      # print int header
la  $a0, header
syscall

la  $t0, IPinHex    
lw  $t0, ($t0)  # IP address in hex

li  $t5, 0xff000000 # AND value
li  $t6, 24     # shiftAmt
li  $t7, 3      # loop count

loop:               
addi    $t7, $t7, -1    # count--
la  $t1, ($t0)  
and $t1, $t1, $t5   # isolate chunk of hex number
srlv    $t1, $t1, $t6   # shift down to the right

li  $v0, 1      # print int
la  $a0, ($t1)
syscall

li  $v0, 4      # print a "."
la  $a0, dot
syscall

srl $t5, $t5, 8 # shift AND value for next iteration
addi    $t6, $t6, -8    # shiftAmt-= 8

bnez    $t7, loop   # while (loop!=0)


la  $t1, ($t0)  # print last int
and $t1, $t1, $t5   # isolate chunk of hex number

li  $v0, 1      # print int
la  $a0, ($t1)
syscall         

exit:               # exit()
li  $v0, 10     
syscall

person nethageraba    schedule 06.11.2014    source источник


Ответы (1)


la - псевдоинструкция. Эта форма может и не быть незаконной в вашем ассемблере, но определенно не имеет смысла. la не обращается к памяти, а просто загружает адрес второго операнда.

Ассемблер GNU (gas) задыхается от вашей инструкции, говоря Error:Expression too complex.

Если ($t0) разрешен (например, в MARS и встроенном ассемблере clang), адрес ($t0), конечно же, $t0, так что у вас есть просто копия "регистр-регистр", для которой вы должны использовать move (это еще один псевдоинструкцию, которая обычно переводится в addu $dst, $src, $0).

Псевдо-инструкция move $dst, $src работает во всех ассемблерах MIPS и имеет правильное семантическое значение для читателей.

Используйте la только по прямому назначению - внесение адреса символа в регистр,
la $t0, my_static_data.

person Jester    schedule 06.11.2014
comment
Хм, интересно, почему МАРС даже позволил мне тогда это сделать. Спасибо за очень обстоятельный ответ, теперь я понял! - person nethageraba; 07.11.2014