Директива .align в сборке MIPS (MARS)

Я делаю проект для своего университета, использую сборку MIPS в программе под названием MARS. У меня есть проблемы с работой с .align. Думаю, я вообще не понимаю, как работает эта директива.

Это пример ошибки, которую дает мне MARS: «Исключение времени выполнения на 0x00400098: адрес не выровнен по границе двойного слова 0x1001017c».

Ошибка возникает, когда я пытаюсь загрузить двойное значение из двойного массива с именем 'v': l.d $f12, ($t1)

This is my code:

.data
    msg1: .asciiz "### SETTE E MEZZO ###\n\n"
    msg2: .asciiz "carta estratta: "

A:
.align 2
 .word 1,2,3,4,5,6,7,8,9,10,    1,2,3,4,5,6,7,8,9,10,  1,2,3,4,5,6,7,8,9,10,  1,2,3,4,5,6,7,8,9,10 
s:
.align 0
 .byte 'c','c','c','c','c','c','c','c','c','c','q','q','q','q','q','q','q','q','q','q','f','f','f','f','f','f','f','f','f','f','p','p','p','p','p','p','p','p','p','p'

v:
.align 3
.double 1,2,3,4,5,6,7,0.5,0.5,0.5,  1,2,3,4,5,6,7,0.5,0.5,0.5,  1,2,3,4,5,6,7,0.5,0.5,0.5,  1,2,3,4,5,6,7,0.5,0.5,0.5

.text .globl main

main: la $ a0, msg1
li $ v0, 4 системный вызов # print stringa titolo

 ### SALVO GLI INDIRIZZI DEGLI ARRAY IN REGISTRI ###
la $s0, A       # $s0 <- &A (indirizzo array numero carte)
la $s1, s       # $s1 <- &s (indirizzo array semi carte)
la $s2, v       # $s2 <- &v (indirizzo array valori carte)

li $s3, 0       # $s3 <- somma carte PLAYER 

jal Player



li $v0, 10      #exit
syscall

Плеер: #PUSH subu $ sp, $ sp, 24 #abbasso lo stack pointer di 20 perchèdev salvarmi 5 registri ciascuno da 4 byte (quindi 5 * 4 = 20 byte) sw $ fp, 20 ($ sp) sw $ ra, 16 ($ sp) sw $ s0, 12 ($ sp) sw $ s1, 8 ($ sp) sw $ s2, 4 ($ sp) sw $ s3, 0 ($ sp) #modifico lo указатель стека в modo che punti alla prima parola del record di attivazione addiu $ fp, $ sp, 16 # ------------------ jal Random move $ s4, $ v0 # numero casuale in $ s4

mul $t0, $s4, 4     # $t0 <- index
add $t1, $s0, $t0   # $t1 <- &A[index]
lw $a0, 0($t1)      #vado a prendere nell'array A una carta a caso in base al numero random che funge da incdice        
li $v0, 1   
syscall         # print del numero della carta
sw $zero, 0($t1)    # A[index] <- 0    in modo che non venga estratto due volte lo stesso numero

add $t1, $s1, $s4   # $t1 <- &s[index]
lb $a0, 0($t1)      #vado a prendere nell'array s il seme
li $v0, 11
syscall 

add $t1, $s2, $t0   # $t1 <- &v[index]  
l.d $f12, ($t1)
li $v0, 3

#POP
lw $s3, 0($sp)
lw $s2, 4($sp)
lw $s1, 8($sp)
lw $s0, 12($sp)
lw $ra, 16($sp)
lw $fp, 20($sp)
addi $sp, $sp, 20
#------------------

jr $ra

Случайный:

li $v0, 42 li $a1, 40 syscall # estrae pseudo-random number da 0 a 9 move $v0, $a0 # numero casuale in $v0 (VALORE DI RITORNO) jr $ra

What I'm doing wrong? I would appreciate it very much if someone could explain it to me. Thank you in advance.


person Jay    schedule 04.07.2018    source источник
comment
Чтобы получить правильное начальное выравнивание, .align следует поместить перед меткой. В противном случае метка может быть по адресу (например) 0x01, но данные размещаются по адресу 0x02 (т.е. пробел). А некоторым нужно больше выравнивания. Итак, делаем: .align 4 A: / .align 0 s: / .align 8 v:   -  person Craig Estey    schedule 05.07.2018


Ответы (1)


В этой строке

mul $t0, $s4, 4     # $t0 <- index

Вы умножили индекс на предполагаемый размер элемента, чтобы получить смещение от начала массива.

Однако двойные значения составляют 8 байт, поэтому индекс нужно было умножить на 8 (то есть сдвинуть влево на 3). Это не соответствует расчету смещения для других массивов - как правило, вы не можете повторно использовать подобный масштабированный индекс.

person harold    schedule 04.07.2018