Нужно ли инициализировать регистры процессора в коде сборки, который вызывается из C? - PullRequest
4 голосов
/ 17 февраля 2011

Я читаю книгу pcasm Пола Картера. Он использует NASM, приложение драйвера C, которое вызывает мой ассемблерный код, и сопутствующую библиотеку, которая упрощает базовый ввод-вывод в сборке.

Вот как выглядит моя функция, которая будет вызываться из C:

segment .text
    global  _asm_main
_asm_main:
    enter   0,0               ; setup routine
    pusha

    mov bx, 0034h   ; bx = 52 (stored in 16 bits)
    mov cl, bl      ; cl = lower 8-bits of bx
    mov eax, ecx
    call print_int

    popa
    mov     eax, 0            ; return back to C
    leave                     
    ret

Функция print_int печатает хранилище значений в eax как целое число. Но это выводит мусор на стандартный вывод:

4200244

Если я инициализирую регистр ecx до 0 с помощью mov ecx, 0000h перед его использованием, я получу ожидаемый результат:

52

Всегда ли требуется инициализация, и если да, есть ли быстрый способ инициализации всех регистров в 0 (или определяемый пользователем инициализатор) из C или NASM?

Я использую XP32, MinGW 4.4.0 и NASM 2.09.04.

Ответы [ 2 ]

4 голосов
/ 17 февраля 2011

Функция print_int выводит значение eax. В вашем коде вы назначаете только младший из четырех байтов eax (a.k.a. al) через следующую цепочку назначений: bl -> cl -> al. Оставшиеся три байта eax остаются неинициализированными. Ваш код наследует те значения, которые были в этих трех байтах в начале вашей процедуры. Вот почему вы получаете мусор.

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

Моя сборка x86 немного ржавая, но я почти уверен, что нет ни одной инструкции, которая бы выставляла все регистры общего назначения в ноль. Если бы вы были так склонны, вы могли бы написать макрос, который бы сделал это для вас.

2 голосов
/ 17 февраля 2011

Да, это необходимо.

Ничего не сделано для вас, в сборе.
Вы должны инициализировать каждый регистр так, как вы этого хотите.

...