Linux x86 NASM - Подпрограмма: распечатать слово от EAX

Так что я'я изучаю сборку Linux x86 с синтаксисом NASM (О боже, не это снова, вы'все думают) Я'Я пытаюсь создать подпрограмму, которая будет просто выводить значение в EAX на стандартный вывод. Код запускается и завершается без ошибок, но ничего не печатается. Я могу'не понимаю, почему. Прежде всего, вот файл, который яработаю в:

segment .bss
    to_print:   resd 1

segment .text
    global print_eax_val

print_eax_val:                  ;       (top)
    push    dword ebx           ;Stack:  edx
    push    dword ecx           ;        ecx
    push    dword edx           ;        ebx
                                ;       (bot)

    mov     ecx,eax             ;ecx = eax

    mov     [to_print],ecx      ;to_print = ecx

    mov     eax, 4              ;sys_write
    mov     ebx, 1              ;to stdout
    add     ecx, 47             ;add 47 for ASCII numbers
    mov     edx, 2              ;double word = 2 bytes
    int     0x80

    mov     eax, [to_print]     ;eax = original val
    pop     edx                 ;pop the registers back from the stack
    pop     ecx
    pop     ebx                 ;Stack: empty

    ret

Это вызывается из моего основного файла, который выглядит следующим образом (это, вероятно, не имеет значения, если я нея что-то упустил).

segment .data
        hello   db      "Hello world!", 0
        newline db      0xA
        len     equ $ - hello
        len2    equ $ - newline

segment .text
        extern print_nl
        extern print_eax_val
        global main

main:
        enter   0,0

        call    print_nl

        mov     eax, 1

        call    print_eax_val

        mov     ebx, 0          ;exit code = 0 (normal)
        mov     eax, 1          ;exit command
        int     0x80            ;ask kernel to quit

print_nl это просто еще одна подпрограмма, которая определяет и печатает новую строку. Это успешно выполняется и печатает новую строку, как ожидалось.

Проблема связана с параметром длины для моегоsys_write вызов? Я'м, давая ему 2, который является размеромdword, который является размером какEAX зарегистрироваться и мойto_print ярлык, который я зарезервировалresd 1, Я пытался изменить длину до 1, 4, 8, 16 и 32 из отчаяния ... Ничего не получалось.

РЕДАКТИРОВАТЬ: Для тех, кто интересуется, вот как я исправил код: (Я буду ставить звездочки на строки, которые я изменил):

segment .bss
    to_print:   resd 1

segment .text
        global print_eax_val

print_eax_val:                      ;       (top)
        push    dword ebx           ;Stack:  edx
        push    dword ecx           ;        ecx
        push    dword edx           ;        ebx
                                    ;       (bot)

        mov     ecx,eax             ;ecx = eax

        mov     [to_print],ecx        ;to_print = ecx

****    add     dword [to_print], 48

        mov     eax, 4              ;sys_write
        mov     ebx, 1              ;to stdout
****    mov     ecx, to_print
        mov     edx, 2
        int     0x80

****    sub     dword [to_print], 48
        mov     eax, [to_print]     ;eax = original val
        pop     edx                 ;pop the registers back from the stack
        pop     ecx
        pop     ebx                 ;Stack: empty

        ret

В принципе,ecx должен содержатьадрес блока, который вы хотите напечатать, а не само значение. Как указано в выбранном ответе, это будеттолько работать, если eax находится в диапазоне 0-9.

РЕДАКТИРОВАТЬ 2Так что я был немного озадачен вторым параметром для sys_write (который хранится вedx). Я думаю, что это просто относится к числу байтов. Так что дляdword, как я использовал, было бы правильно использовать 4 там, потому что двойное слово составляет 4 байта или 32 бита. Я'Я предполагаю, что это сработало, потому что x86 имеет младший порядок. Так в памяти шестнадцатеричное значениеto_print будет выглядеть так:

90 00 00 00

И с предоставленной длиной два, sys_write получает:

90 00

Так что ценность, к счастью, нене испортился.

Я позже изменил код для храненияto_print вместо этого, используя байтresb 1 и доступ к нему с помощьюbyte вместоdword... Байт здесь хорошо, потому что я знаю, чтоя не собираюсь даватьto_print значение выше 9.I '

Ответы на вопрос(2)

Ваш ответ на вопрос