2015-04-29 2 views
5

Я пытаюсь получить этот код на С:Преобразование C до сборки NASM с вопросом сегментации

main() 

{int x, y, count ; 

    count = 0 ; 
    x = 10 ; 
    y = 2 ; 
    while (y < x) 
    { x = x + 1 ; 
     y = y + 2 ; 
     count = count + 1 ; 
    } 

    printf(“ It took %d iterations to complete loop. That seems like a  lot\n”,count) ; 
} 

его NASM эквивалент, который у меня есть это до сих пор:

segment .data 

out1 db "It took ", 0 
out2 db "%i ", 0 
out3 db "iterations to complete the loop. That seems like a lot.", 10, 0 

segment .bss 

segment .text 

global  main 
extern printf 

main: 

    mov eax, 0  ;count 
    mov ebx, 10  ;x 
    mov ecx, 2  ;y 

    jmp  lp 

    mov eax, 0 
    ret 

lp: 
    cmp ecx, ebx ;compare y to x 
    jge end  ;jump to end if y >= x 
    add eax, 1 
    add ebx, 1 
    add ecx, 2 
    jmp lp 

end: 

    push out1 
    call printf 

    push eax 
    push out2 
    call printf 

    push out3 
    call printf 

Я постоянно получаю и я не понимаю, почему это происходит. Я пробовал добавлять в печати заявления везде и не могу найти, где находится ошибка. Любой совет будет полезен! Спасибо!

+0

Ваш ASM кажется, хорошо для меня. – peterh

+0

У вас есть инструкция 'ret' после' printf's? – Diego

+0

Да, я устал, что он не позаботился о проблеме сегментации :( – mm19

ответ

0

Я думаю, что вы не следуете вызывающему соглашению для printf (это cdecl IIRC).

  1. абонент должен очистить стек после вызова
  2. и EAX будет затерт первым вызовом printf с его возвращаемое значение

номер один будет вызывать проблемы при возвращении из main. На самом деле, нет ret инструкции после printf с которой вызывает выполнение идти, пока что-то пойдет не так :)

Добавить после печати:

add  esp, 16 ; Fix stack, usually it's done after each call 
        ; with the appropiate values. 
        ; In this way (one fixup for many calls) stack 
        ; grows unnecessarily 
    xor  eax, eax ; set return value to 0 
    ret    ; Return from main 

Хотя это не заботиться о проблеме номер два.

+0

Спасибо, что на самом деле помогло немного, я посмотрю, если это сработает. – mm19

+0

Diego, так как это автономная программа сборки, есть нет 'main' и не нужно возвращаться.Что нужно сделать syscall, чтобы выйти на очистку при завершении программы. Код выхода установлен в' ebx', для systall ** x86 ** для выхода есть '1' (см.: '/ usr/include/asm/unistd_32.h') и идет в' eax', тогда ядро ​​вызывается для выполнения команды 'int 0x80' или' int 80h'. –

+0

@ DavidC.Rankin: Выполнение выхода системный вызов вместо возврата явно прекрасен, но эта программа явно имеет функцию «main». Большинство программ сборки, связанных со стандартной библиотекой C, будут иметь один. –

0

Обновленный и полный пример:

segment .data 
out1 db  "It took %d iterations to complete loop. That seems like " 
     db  "a lot.", 0aH, 00H 
segment .bss 
segment .text 
     global main 
     extern printf 
main: xor  eax, eax 
     mov  ebx, 10 
     mov  ecx, 2 
loop0: inc  ebx 
     add  ecx, 2 
     inc  eax 
     cmp  ecx, ebx 
     jl  loop0 
     push eax 
     push offset out1 
     call printf 
     add  esp, 8 
     xor  eax, eax 
     ret 
     end 
+0

да, вот как это должно быть сделано :) – Diego

+0

я все еще получаю ошибку сегментации с изменениями – mm19

0

Если вы не получили его разобрали еще, проблема связана с eax получения лупили на вашем printf вызова. Как исправить? Сохраните его в буфер до первого вызова printf и загрузите eax перед вторым. Например. добавить:

segment .bss 

buffer resd 1   ; reserve 32 bit buffer 
... 
mov  [buffer], eax ; save eax in the buffer 

push out1 
call printf 

mov  eax, [buffer] ; load eax from the buffer 

push eax 
push out2 
call printf 

push out3 
call printf 

xor  ebx, ebx   ; exit nicely 
mov  eax, 1 
int  0x80 

Использование/выход

$ ./bin/pt 
It took 8 iterations to complete the loop. That seems like a lot. 
+0

Я не уверен, что я бы потратил время и усилия на кодирование буфером для него, когда у вас есть совершенно хороший стек, просто сидящий, ожидающий использования :-) Другими словами, 'push eax',' pop eax'. – paxdiablo

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

  • Нет связанных вопросов^_^