Сборка x86 (masm32) вывод умноженного числа дает ненужные символы

Ради этого я возвращаюсь к сборке через несколько месяцев, и у меня возникают проблемы с умножением двух чисел и выводом результата. Вот мой код:

.386
.model flat, stdcall 
option casemap :none 

include \masm32\include\windows.inc 
include \masm32\include\kernel32.inc 
include \masm32\include\masm32.inc 
includelib \masm32\lib\kernel32.lib 
includelib \masm32\lib\masm32.lib

.data 
     sum sdword 0
.code 
start:
mov ecx, 6        
xor eax, eax                  
mov edx, 7               
mul edx                  
push eax
pop sum
lea eax, sum
call StdOut
push 0 
call ExitProcess
end start 

Он выводит что-то вроде P &aeffiini,.

ВОПРОС: Почему он выводит эту случайную строку символов и как я могу это исправить?

Заранее спасибо.


person Progrmr    schedule 20.08.2012    source источник
comment
Я не вижу никакого кода для преобразования результата (числа) в строку, чтобы он был готов к печати. StdOut (вероятно) не является функцией, поэтому ее вызов будет принимать какое-то полуслучайное значение, обрабатывать его как адрес и вызывать этот адрес — почти наверняка не то, что вы намеревались.   -  person Jerry Coffin    schedule 20.08.2012


Ответы (2)


Поскольку StdOut печатает строки с завершением NULL, а не числа. Сначала нужно преобразовать число в строку. MASM32 имеет dwtoa. Кроме того, вы неправильно умножаете. ты умножаешь на eax

include masm32rt.inc

.data?
lpBuffer    db 12 dup (?)

.code 
start:
    mov     ecx, 6        
    mov     eax, 7               
    mul     eax    

    push    offset lpBuffer
    push    eax
    call    dwtoa 

    push    offset lpBuffer             
    call    StdOut

    inkey
    push    0 
    call    ExitProcess
end start 
person Gunner    schedule 20.08.2012
comment
Спасибо, это прекрасно работает. Ради интереса, зачем вам нужно делать push offset lpBuffer? А что такое inkey? - person Progrmr; 20.08.2012

Ваш вывод контролируется тем, что у вас есть в функции StdOut, которую вы нам не показали. Более чем вероятно (учитывая ваше описание), он берет символ code в аккумуляторе и выводит эквивалентный символ.

Если это так, вам, вероятно, нужно взять значение в eax и определить, какие символы необходимо вывести на его основе. Затем вызовите StdOut для каждого из них.

Псевдокод для этого будет примерно таким:

eax <- value to print
call print_num
exit

print_num:
    compare eax with 0
    branch if not equal, to non_zero

    eax <- hex 30                       ; Number was zero,
    jump to StdOut                      ;   just print single digit 0

non_zero:
    push eax, ebx, ecx                  ; Save registers that we use
    ecx <- 0                            ; Digit count
loop1:
    compare eax with 0                  ; Continue until digits all pushed
    jump if equal, to num_pushed

    increment ecx                       ; Another digit
    ebx <- eax                          ; Work out what it is
    eax <- eax / 10
    eax <- eax * 10
    ebx <- ebx - eax
    push ebx to stack                   ; Then push it,
    jump to loop1                       ;  and carry on

num_pushed:
    pop eax from stack                  ; Get next digit
    eax <- eax + hex 30                 ; Print it out
    call StdOut
    decrement ecx                       ; One less digit to go
    jump if not zero, to num_pushed     ; Continue if more

    pop ecx, ebx, eax from stack        ; Clean up stack and return
    return

Если это не так, вам просто нужно выяснить, что на самом деле делает StdOut, и настроить код так, чтобы он соответствовал требованиям этой функции.

person paxdiablo    schedule 20.08.2012