2015-02-05 2 views
1

Ненавижу задавать такие основные вопросы. Кажется, я ленив! Но я потратил часы, просматривая документацию, и по какой-то причине я не могу опустить голову прямо в эту маленькую точку.Невозможно выяснить, как напечатать номер в MASM32

Я хочу напечатать символ «4» на экране. Я могу сделать это как строку, но не из значения ascii.

Вот рабочий код:

include c:\masm32\include\masm32rt.inc 
.data 
    num4 db "4", 10,0 
.code 
start: 
    invoke StdOut, addr num4 
    inkey 
    invoke ExitProcess, 0 
end start 

Я просто хотел сделать шаг ребенка оттуда и печать символов ASCII 52 (который является «4»). Вот моя лучшая попытка до сих пор:

include c:\masm32\include\masm32rt.inc 
.data 
.code 
start: 
    myvar db 52 
    invoke StdOut, myvar 
    inkey 
    invoke ExitProcess, 0 
end start 

Он собирает и ссылки без проблем, но затем падает, когда я запускаю его. Я знаю, что в конце он не имеет 0 символов, но у invoke StdOut, myvar,0 слишком много аргументов для StdOut.

Моя конечная цель состоит в том, чтобы иметь возможность напечатать несколько число цифр, как описано Алексея Фрунзе здесь:

x86 assembly (masm32) - how to split multi-digit data into individual characters

Но так как я имею так много проблем с синтаксисом, я предпринимаю шаги ребенка , Я нашел это, но это не объясняет, как сделать добавить 48 часть синтаксически:

x86 assembly - how to show the integer 2, not the second ASCII character

Пожалуйста, помогите мне пройти эти открытия препятствия, и спасибо!

ответ

5

Во-первых, myvar db 52 находится не в том месте. Когда программа запускается, компьютер приходит в db 52 и рассматривает это как инструкцию. Во-вторых, значение 0 (не указывать символ) не является аргументом для StdOut и должно быть в конце данных. StdOut нуждается в аргументе указатель в строку с нулевым завершением. Вы не можете дать ему прямое значение, функция будет принимать это как указатель. BTW: Учтите, что StdOut является функцией MASM32, а не функцией ядра Windows. Ваша программа должна выглядеть следующим образом:

include c:\masm32\include\masm32rt.inc 
.data 
    myvar db 52, 0 
.code 
start: 
    invoke StdOut, ADDR myvar 
    inkey 
    invoke ExitProcess, 0 
end start 

Вы должны сначала создать строку перед выводом его с «STDOUT». Если у вас нет строки, но числа, вам нужно преобразовать ее в строку (ключевые слова для Google: «assembly convert integer to ascii»). Трюк состоит в том, чтобы разделить число на 10 и сохранить остаток. Другой трюк заключается в использовании макроса MASM32.

INCLUDELIB C:\masm32\lib\masm32.lib 
INCLUDE C:\masm32\include\masm32rt.inc 

.DATA 
    decimalstr db 16 DUP (0) 
    myvar db 52 

.CODE 

start PROC 

    movzx eax, myvar   ; Load an 8-bit-byte into a 32-bit-register 
    lea edi, decimalstr  ; Load the address of decimalstr 
    call EAX_to_DEC 
    invoke StdOut, addr decimalstr 

    movzx eax, myvar 
    printf ("\nAnd the lazy MASM32 way: %u\n",eax) 

    invoke ExitProcess, 0 
start ENDP 

EAX_to_DEC PROC    ; ARG: EDI pointer to string buffer 
    mov ebx, 10    ; Divisor = 10 
    xor ecx, ecx   ; ECX=0 (digit counter) 
    @@:      ; First Loop: store the remainders 
    xor edx, edx 
    div ebx     ; EDX:EAX/EBX = EAX remainder EDX 
    push dx     ; push the digit in DL (LIFO) 
    add cl,1    ; = inc cl (digit counter) 
    or eax, eax   ; AX == 0? 
    jnz @B     ; no: once more (jump to the first @@ above) 
    @@:      ; Second loop: load the remainders in reversed order 
    pop ax     ; get back pushed digits 
    or al, 00110000b  ; to ASCII 
    stosb     ; Store AL to [EDI] (EDI is a pointer to a buffer) 
    loop @B     ; until there are no digits left 
    mov byte ptr [edi], 0 ; ASCIIZ terminator (0) 
    ret      ; RET: EDI pointer to ASCIIZ-string 
EAX_to_DEC ENDP 

END start 

Также посмотрите here.

+0

Этот ответ изумительный и дает мне руководство для моей будущей цели (хотя я еще не понимаю каждый аспект этого ответа, но ваши комментарии очень полезны, и я предполагаю, что это придет со временем и настойчивостью) , Но у вас также есть ответ на нерабочий код, который я представил? –

+0

О, а также, почему вы объявили clrf? Кажется, он нигде не используется. –

+0

@Choirbean: Пожалуйста, взгляните на обновленный ответ. Я сделал все возможное :-) – rkhb