2017-05-09 2 views
1

Ich lerne AT & T x86 Assembly in diesen Tagen. Ich schreibe den Code, der zwei 32-Bit-Ganzzahlen multipliziert, ohne "*" zu verwenden. Das Problem ist, dass der Debugger mir sagt, dass ich Segmentierungsfehler habe. Hier ist mein Code.Beginnen Sie einfach mit Assembly (GAS), und hat Segmentierung Fehler in diesem Kurzcode

.global _start 


.data 

a: 
    .long 0 

b: 
    .long 0 

count: 
    .long 0 

.text 

_start: 

    movl $0, %eax 
    movl $a, %ebx 
    movl $b, %ecx 
    movl $0, %edx 

    for_mult: 
     cmpl $32, count 
     je end_for_mult 

     carry_bit: 
      shr $1, %ecx 
      jnc is_zero 

      addl (%ebx), %eax 

      is_zero: 
       shl $1, %ebx 

     incl count 
     jmp for_mult 
    end_for_mult: 

done: 
    movl %eax, %eax 

Der Debugger zeigt, dass Segmentierungsfehler bei "ADDL (% ebx),% eax" erscheint, und ich kann nicht herausfinden, warum. Danke für Ihre Hilfe!

+0

Sie sollten überlegen, was 'shl $ 1,% ebx' zu' ebx' und wie sich das auf 'addl (% ebx),% eax' in * der nächsten * Runde der Schleife auswirkt. –

+0

Wenn der Debugger Segmentierungsfehler meldet und auf eine Anweisung zeigt, können Sie die verwendete Speicheradresse überprüfen (Wert in 'ebx' in diesem Fall). Dann können Sie mit Ihrem zugewiesenen Speicher überprüfen (normalerweise '.data' /' .rodata' Sektionsbeschriftungen), wenn dieser auf eine Stelle zeigt, wo Sie wollen. Dann können Sie mit der Suche beginnen (wahrscheinlich durch schrittweises Durchlaufen der Code 1-Anweisung), warum Sie den gültigen/erwarteten Speicher verloren haben. Übrigens, Sie haben noch einige Register frei, warum benutzen Sie nicht auch einen für "count"? Warum eigentlich nicht nur Register verwenden und speichern im Speicher nur Ergebnis? Es ist normalerweise einfacher und schneller. – Ped7g

Antwort

2

Sie mischen Adressen und Werte.

die $ -Zeichen entfernen in

movl a, %ebx 
movl b, %ecx 

(Ihr Code bewegt sich tatsächlich um die Adressen von a und b zu den Registern und nicht die Werte!)

die Halterung entfernen um %ebx

addl %ebx, %eax 

Sie möchten den Wert von ebx nicht den Wert, auf den ebx zeigt.