MIPS Adresă greșită în citirea datelor/stack-ului (Programare, Asamblare, Mips, Spim)

Tenze a intrebat.

Am petrecut ore întregi uitându-mă la asta, tipărind adrese și nu pot să-mi dau seama. Acesta este un simplu program de asamblare rulat prin QTSpim. Programul este menit să preia valori pentru o matrice de dimensiune 20, să găsească două cele mai mici numere întregi dintr-o matrice, să le adauge și să le returneze la main unde sunt apoi stocate în memorie în locații imediat după matrice.

Programul preia cele 20 de valori pentru matrice, dar apoi încearcă să calculeze și emite adresa Bad în data/stack read: 0x10040000. Toate celelalte date ale mele se află în locațiile de memorie 0x100100XX, nu am idee de ce apare 40000.

.data
Fresh: .space 80
freshSmallestSum: space 4

.text
sumMin:
    lw      $t2, 0($a0) # $t2 = smallest array[i]
    addi    $t4, $t0, 1 # $t4 = i + 1
    sll     $t4, $t4, 2 # $t4 = i * (2^2)
    add     $t4, $t4, $a0   # $t4 = absolute address array[i+1]
    lw      $t3, 0($t4) # $t3 = array[i+1]
    li      $t4, 2      # i = 2
    ble     $t2, $t3, loopSmall # if $t2 <= t3 jump
    move    $t9, $t2
    move    $t2, $t3
    move    $t3, $t9
loopSmall:
    bge     $t4, $t1, ret1
    sll     $t5, $t4, 2 # $t5 = i * (2^2)
    add     $t5, $t5, $a0   # absolute address array[i]
    lw      $t5, 0($t5) # $t5 = array[i]
    ble     $t3, $t5, next2 # if $t3 <= array[i], jump
    move    $t3, $t5    # else $t3 = array[i]
    ble     $t2, $t3, next2 # if $t2 <= $t3, jump
    move    $t9, $t2    # else swap two smallest
    move    $t2, $t3
    move    $t3, $t9
next2:
    addi    $t4, $t4, 1 # i++
    j   loopSmall
ret1:
    add     $v0, $t2, $t3   # $v0 = smallest + secondSmallest
    jr      $ra

.text
.globl main
main: 
    li      $t3, 0
    li      $t0, 0      # i = 0
    li      $t1, 20     # $t1 = 20
    la      $s2, Fresh

inLoop: 
    bge $t3, $t1, next  # If $t3 > array length, jump
    sll     $t2, $t3, 2
    add     $t4, $t2, $s2   # Absolute address of fresh
    li      $v0, 5
    syscall
    sw      $v0, 0($t4)
    addi    $t3, $t3, 1 # Increment counter
    j       inLoop      
move        $a0, $s2    # $a0 = address Fresh
    jal     sumMax      # Get max sum of Fresh
    la      $t1, freshLargestSum
    sw      $v0, 0($t1) # Store sum in freshLargestSum

    move    $a0, $s2
    jal     sumMin      # Get min sum of Fresh
    la      $t1, freshSmallestSum
    sw      $v0, 0($t1) # Store sum in freshSmallestSum

exit:       li  $v0, 10
    syscall

Comentarii

  • Folosiți simulatorul pentru a trece o singură dată prin cod și a vedea care instrucțiune dă eroare. Apoi verificați valorile registrelor și identificați care este defectă, apoi mergeți înapoi pentru a vedea cum a ajuns la valoarea defectă. PS: Nici măcar nu pot găsi eticheta next, , eroare de copy-paste sau chiar nu o ai? De asemenea, sumMin pare să se aștepte la dimensiunea matricei în $t1 dar care conține adresa de freshLargestSum în acel moment. –  > Por Jester.
  • Scuze – cu siguranță a fost o eroare de copy paste – programul este mult mai lung decât acest segment de cod. Încerc să tai doar bucățile relevante. Și $t1 a fost eroarea! Mulțumesc foarte mult – acea mică schimbare de registru nu era aproape în cod de piesa sumMin, așa că nu am prins-o. Ore întregi de privit în viitor fixate de comentariul tău, mulțumesc! –  > Por Tenze.
  • Ar trebui să testați întotdeauna codul pe care îl postați efectiv pentru ajutor la depanare, mai ales dacă sunteți începător. –  > Por Peter Cordes.
1 răspunsuri
officialgupta

Cea mai mare parte a codului de aici arată foarte bine, dar acesta nu este fișierul complet?

S-ar părea că funcția ta sumMin vrea dimensiunea matricei ca t1, dar dă o adresă freshLargestSum?

Ați încercat să parcurgeți codul linie cu linie?În special cu MIPS, majoritatea erorilor sunt de obicei suprascrierea registrelor de care avem nevoie mai târziu în cod; mai ales când sărim înapoi.

O bună tehnică de depanare constă, de asemenea, în a testa dacă toate funcțiile funcționează independent, așa cum se așteaptă; dacă este așa, știți că eroarea se află în codul principal și este probabil legată de:

  • registre suprascrise
  • jal în locul greșit
  • Suprascrierea registrului de întoarcere
  • Logică incorectă

Sperăm că acest lucru vă ajută să vă rezolvați problema!