2013-10-26 4 views
0

Каждый раз, когда я пытаюсь запустить свой код, я получаю ошибку сегментации. Может ли кто-нибудь указать мне в правильном направлении на то, что может быть причиной этого?Ошибка сегментирования языка сборки Intel

Компилятор на Linux, что я запускаю код с помощью PuTTY.

Я думаю, что это связано с mov dword [esp + #], но не знаю, как его зафиксировать.

%include "asm_io.inc" 
segment .data 
display db "Area: %d | Points: %d | Probability: %d/%d",10,0 
display2 db "Expected Outsome: %d", 0 
radiusone db "Enter number ", 0 
radiustwo db "Enter number ", 0 
radiusthree db "Enter number ", 0 
radiusfour db "Enter number ", 0 
pointsone db "Enter number ", 0 
pointstwo db "Enter number ", 0 
pointsthree db "Enter number ", 0 
pointsfour db "Enter number ", 0 

segment .bss 

r1 resd 1 ;Radius 
r2 resd 1 
r3 resd 1 
r4 resd 1 
p1 resd 1 ;Points 
p2 resd 1 
p3 resd 1 
p4 resd 1 
ca1 resd 1 ;Computed Area 
ca2 resd 1 
ca3 resd 1 
ca4 resd 1 
pi1 resd 1 ;radius*radius 
pi2 resd 1 
pi3 resd 1 
pi4 resd 1 
pb1 resd 1 ;Probability 
pb2 resd 1 
pb3 resd 1 
pb4 resd 1 
eo resd 1 ; Expected Outcome 

segment .text 
     global asm_main 
     extern printf 
asm_main: 
     enter 0,0    
     pusha 

    mov eax, radiusone 
    call print_string 
    call read_int 
    mov [r1], eax 

    mov eax, radiustwo 
    call print_string 
    call read_int 
    mov [r2], eax 

    mov eax, radiusthree 
    call print_string 
    call read_int 
    mov [r3], eax 

    mov eax, radiusfour 
    call print_string 
    call read_int 
    mov [r4], eax 
    ;************************ 

    mov eax, pointsone 
    call print_string 
    call read_int 
    mov [p1], eax 

    mov eax, pointstwo 
    call print_string 
    call read_int 
    mov [p2], eax 

    mov eax, pointsthree 
    call print_string 
    call read_int 
    mov [p3], eax 

    mov eax, pointsfour 
    call print_string 
    call read_int 
    mov [p4], eax 
    ;************************ 

    mov eax, [r1] 
    imul eax, [r1] 
    mov [pi1], eax 

    mov eax, [r2] 
    imul eax, [r2] 
    mov [pi2], eax 

    mov eax, [r3] 
    imul eax, [r3] 
    mov [pi3], eax 

    mov eax, [r4] 
    imul eax, [r4] 
    mov [pi4], eax 
    ;********************** 

    mov eax, [r1] 
    mov [ca1], eax 

    mov eax, [ca2] 
    sub eax, [pi1] 
    mov [ca2], eax 

    mov eax, [ca3] 
    sub eax, [pi2] 
    mov [ca3], eax 

    mov eax, [ca4] 
    sub eax, [pi3] 
    mov [ca4], eax 
    ;******************** 

    mov eax, [r1] 
    imul eax, [p1] 
    mov [pb1], eax 

    mov eax, [r2] 
    imul eax, [p2] 
    mov [pb2], eax 

    mov eax, [r3] 
    imul eax, [p3] 
    mov [pb3], eax 

    mov eax, [r4] 
    imul eax, [p4] 
    mov [pb4], eax 
    ;*********************** 

    mov eax, [pb1] 
    add eax, [pb2] 
    add eax, [pb3] 
    add eax, [pb4] 
    mov [eo], eax 
    ;************************ 

    sub easp 10h 

    push dword [pi4] 
    push dword [ca1] 
    push dword [p1] 
    push dword [r1] 


    mov dword [esp], display 
    call printf 
    add esp, 10h  


    popa 
    mov  eax, 0   
    leave      
    ret 

Обновление: Я добавил изменения в код с использованием поп-функции вниз, где вызов, и теперь это избавиться от ошибки сегментации и теперь я получаю выход, однако, не значения I» d нравится.

выход:

Площадь: 134520364 | Очки: 134520380 | Вероятность: 134520396/134520424

Площадь: 134520260 | Очки: 134520276 | Вероятность: 134520292/134520320

Площадь: 134520260 | Очки: 134520276 | Вероятность: 134520292/134520320

, когда он должен быть

Площадь: 1 | Очки: 17 | Вероятность: 1/64

У меня нет петли, поэтому я не уверен, что было напечатано 3 строки.

UPDATE2:

Внесены изменения в толчке по предложению, внесенному я знаю, получить выход выглядит лучше ...

Площадь: 17 | Очки: 1 | Вероятность: 64/134519817

Несмотря на то, должно быть:

Площадь: 1 | Очки: 17 | Вероятность: 1/64

как я его в стек

1, 17, 1, 64 .... и моя строка для него является:

дисплей дб " Площадь:% d | Очки:% d | Вероятность:% d /% d», 10,0

Так это выглядит, как они случайно помещены

Нужно ли добавитьmov dword [esp + 4], display?

+0

Похоже, вы просто перемещаете параметры в стек для вызова 'printf'. Вы не можете этого сделать, поскольку переписываете другие элементы в стеке. Вы должны «нажать» параметры в стек, сделать вызов, а затем восстановить указатель стека туда, где он был до того, как вы сделали толки. – lurker

+0

Я сделал то, что вы сказали, и он избавился от ошибки сегментации и дал мне выход, хотя и неверный вывод. Я просмотрел свой код и не знаю, почему он дал мне эти цифры. Я могу только предположить, что эти числа являются ячейками памяти? – user2922055

ответ

2

Ошибка seg происходит из-за неправильного выхода из вашей программы. ret не подходит для выхода из программы в Linux или Windows. Windows это ExitProcess, а Linux - системный вызов или вызов exit из библиотеки C. В вашем случае вы связываетесь с C Library, чтобы использовать printf, и gcc добавит код запуска, который запускается перед вашим кодом, поэтому вы должны позвонить exit, чтобы правильно завершить работу вашей программы.

Другие проблемы есть, но это устранит неисправность seg. Кроме того, сделайте так, чтобы mbratch упоминал и передавал параметры, нажимая и регулируя esp после вызова printf

0

Прежде всего, линии mov dword [esp + #], ... переписывают то, что делают линии push ..., поэтому вам следует избавиться от них. Во-вторых, те цифры, которые вы выводите, выглядят как адреса - действительно, когда вы делаете, то есть push pi4, вы нажимаете адрес переменной pi4. Вместо этого вы должны нажать содержимое переменной, с push dword [pi4].

+0

Спасибо. Сейчас я на правильном пути. Переход к обновлению. Все еще немного смешано, но все еще продолжается – user2922055

Смежные вопросы