x86 assembly (masm32) output multiplied number pro

2019-08-20 12:01发布

问题:

I'm coming back to assembly for the sake of it after a few months and I'm having trouble getting two numbers to multiply and output the result. Here's my code:

.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 

It outputs something like P &aeffiini,.

QUESTION: Why does it output that random character string, and how can I fix it?

Thanks in advance.

回答1:

Because StdOut prints NULL terminated strings NOT numbers. You need to convert the number to a string first. MASM32 has dwtoa. Also, your multiplying wrong. you multiply with 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 


回答2:

Your output is controlled by whatever you have in the StdOut function, which you haven't shown us. More than likely (given your description), it takes the character code in the accumulator and outputs the equivalent character.

If that's the case, what you probably need to do is to take the value in eax and work out which characters need to be output based on that. Then, call StdOut for each of them.

The pseudo-code for that would be something like:

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

If that's not the case, you will simply have to figure out what StdOut actually does and adjust your code to meet the requirements of that function.