2016-03-21 6 views
0

Dieses Montageprogramm ist ein Fizz-Spiel. Es sollte den Regeln für das Kinderzählspiel Fizz folgen: Es sollte von 1-100 drucken, und wenn die Zahl durch 5 teilbar ist, oder die Ziffer 5 enthält, ersetzen Sie die Zahl durch das Wort "Fizz".Montageprogramm: Game of Fizz

Ich habe derzeit ein Problem mit diesem Programm. Das Programm läuft aber die Ausgabe ist: Nummer = 1 Segmentierung Fehler (Core Dumped) Ich würde mich freuen, wenn jemand mir dabei helfen kann. Dank

enter cextern printf 
section .data 
fmt: db "number = %d", 10, 0 ; printf format string 
fmt2: db " %s",10,0 
fmt3: db " %s ", 10, 0 
section .text 
global main 
main: 
    push ebx  ; EBX is callee saved so we need to save it so that it 
        ; it can be restored when we RETurn from main 
    xor ecx,ecx ; ebx = 0 (counter) 
L1: 
    inc ecx 
    xor eax,eax 
    mov eax,ecx 
    xor ebx,ebx 
    xor edx,edx 
    mov ebx,5 
    idiv ebx 
    cmp edx,0 
    jz Fizz 
    push ecx  ; 2nd parameter is our number to print 
    push fmt  ; 1st parameter is the address of the format string 
    call printf 

    ;add sp, 8  ; We pushed 8 bytes prior to printf call, we must adjust the stack 
        ; by effectively removing those bytes. 
      ; counter += 1 
    cmp ecx,100 
    jle L1  ; If counter is <= 100 go back and print again 
    jmp end 
Fizz: 
    mov ebx,0x4669 
    mov eax, 0x7A7A 
    push ebx 
    push eax 
    push fmt2 
    call printf 
    pop eax 
    pop ebx 

    jmp L1 
end: 
    pop ebx  ; Restore EBX before exiting main per calling convention 
    ret   ; RETurn from main will cause program to gracefully exit 
        ;  because we are linked to the C runtime code and main was 
        ;  called by that C runtime code when our program started.ode here 
+1

Haben Sie versucht, es in einem Debugger auszuführen und zu sehen, wo es abstürzt? –

+1

Etwas darüber [sieht bekannt] (http://Stackoverflow.com/a/36092926/3857942) –

+0

@michel Petch, ja es stürzt bei 0x080482 in ??(). wenn ich die Info-Register zu tun, das ist, was es gibt mir: EAX 0x0 0 ECX 0x1 1 edx 0x1 1 ebx 0x5 5 esp 0xffffd810 0xffffd810 EBP 0x0 0x0 esi 0x1 1 edi 0xf7fb3000 -134.533.120 eip 0xf7ff06c1 0xf7ff06c1 <_dl_runtime_resolve + 1> EFLAGS 0x202 [IF] cs 0x23 35 ss 0x2b 43 ds 0x2b 43 es 0x2b 43 fs 0x0 0 gs 0x63 99 (gDB) – anonymous

Antwort

0

Ihr Programm abstürzt, weil Sie nicht für ECX während eines Funktionsaufruf Ändern Konto und Sie haben unausgewogen Push/Pop geht. Beachten Sie hier:

push ecx 
push fmt 
call printf 

aber man kann nie pop diese beiden Werte wieder aus dem Stapel. Da ECX im Aufruf nicht beibehalten wird und Sie keine anderen Operationen ausführen, nachdem die Funktion zurückkehrt, verlassen Sie sich auf was auch immer ECX nach dem Funktionsaufruf sein. Wenn Sie sich die calling conventions ansehen, werden Sie feststellen, dass ecx bei Funktionsaufrufen nicht erhalten bleibt. Sie können es unverändert finden, aber Sie können sich nicht darauf verlassen. Du musst es bewahren.

Dies führt den Code sofort zu end springen und versuchen, ret. Dies wird sofort abstürzen, weil Sie jetzt versuchen, an die Adresse des Formatzeichens zurückzukehren, da das, was als nächstes auf dem Stapel ist.

Vielleicht das?

push ecx 
push fmt 
call printf 
pop ecx ; fmt 
pop ecx ; ECX 
cmp ecx, 100 
jle end 
+0

ok, ich habe es zu dem geändert, das Sie sagten, und wenn ich es laufen lasse, druckt es die Nummern 1 bis 4 und gibt dann einen Segmentierungsfehler (core dumped). Was kann ich tun, um das zu beheben? – anonymous

+0

Wenden Sie die gleichen Prinzipien auf die anderen unsymmetrischen Push/Pop-Kombinationen an, die Sie im Code haben. Ich bemerkte mindestens ein anderes unausgewogenes Set. –

+0

Könnten Sie sagen, welche speziell? – anonymous