Факториальная функция в сборке NASM x86 идет не так - PullRequest
1 голос
/ 22 апреля 2019

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

Я знаю, что пролог и эпилог факторной функции не требуются, потому что я не использую стек, но для меня код более читабелен;)

Вот мой код:

global main
extern printf

section .data
    message db "%03X", 0x10, 0x0

section .text
main:
    mov eax, 5
    call factorial
    push eax
    push message
    call printf
    add esp, 0x8
    mov eax, 1
    mov ebx, 0
    int 0x80

factorial:
    push ebp
    push edx
    mov ebp, esp
    mov edx, eax
    cmp edx, 0
    jne not_equal_zero
    mov eax, 1
    jmp exit
not_equal_zero:
    mov eax, edx
    sub eax, 1
    call factorial
    imul eax, edx
exit:
    mov esp, ebp
    pop edx
    pop ebp
    ret

1 Ответ

1 голос
/ 22 апреля 2019

Библиотека C - я полагаю, вы используете библиотеку GCC - не выводит результат printf сразу. Скорее, он хранится в отдельной памяти, называемой буфером, и выводится случайно. В этом случае программа будет завершена на int 0x80/eax=1 быстрее, чем будет очищен буфер. Вы можете вставить ручную промывку:

...
extern fflush
...
push 0
call fflush
add esp, 4
...

Лучшее решение - использовать функцию C exit. Заменить

mov ebx,0
mov eax,1
int 0x80

от

push 0
call exit

или просто замените на

ret

В этом случае вам не нужно очищать буфер вручную. Это будет exit или ret для вас.

Кстати: LF (перевод строки) кодируется как 10 десятичный и 0x0A шестнадцатеричный.

...