簡體   English   中英

x86 nasm 匯編,如何正確打印乘法結果?

[英]x86 nasm assembly, how to print multiplication result correctly?

所以我在 Stack Overflow 上找到了很多答案,但我仍然無法讓它工作。 我的代碼有什么問題?

        mov al, 12
        mov bl, 12
        mul bl          ; answer in ax
        aam

        mov bx, 10          ; Divisor constant
        xor cx, cx          ; Clear counter
        .a: xor dx, dx      ; Clear dx
            div bx          ; Divide ax with bx, quotient in al, remainder in ah 
            mov dh, ah      ; Move ah to dh, so we can push the 16 bit register of dx
            push dx         ; Push dx which contains the remainder
            inc cx          ; Increment counter
            test al, al     ; If al (the quotient) is not zero, loop again. 
            jnz .a          
        .b: pop dx          ; Pop the last remainder to dx from stack
            add dx, '0'     ; Add '0' to make it into character
            push cx         ; Push loop counter to stack so printing wont interfere with it
            mov eax, 4      ; 
            mov ebx, 1      ;
            mov ecx, edx    ; Print last popped character
            mov edx, 1      ;
            int 0x80        ;
            pop cx          ; Pop the loop counter back to cx
            loop .b         ; loop for as long as cx is not 0

AAM指令可用於結果最多為 2 位的情況。 在你的情況下 12 x 12 = 144,所以這是不行的。

您使用的轉換循環幾乎是正確的,但是您正在混合與DIV指令相關的大小。 如果您給DIV一個字節大小的操作數,那么該操作會將AX除以該字節,余數將在AH中。 如果您給DIV一個字大小的操作數,那么該操作會將DX:AX除以該字,余數將在DX中。

因為您正在編寫 32 位代碼,所以最好也使用 32 位寄存器編寫轉換。

不要使用數字計數器,而是在堆棧上使用哨兵。 顯示時無需保留ECX

顯示 function 需要ECX中的指針。 只需為此使用堆棧指針並在打印后彈出值。

    mov   al, 12
    mov   bl, 12
    mul   bl               ; answer in AX
    movzx eax, ax

    mov   ebx, 10          ; Divisor constant
    push  ebx              ; Sentinel
.a: xor   edx, edx
    div   ebx              ; Divide EDX:EAX with EBX, quotient EAX, remainder EDX 
    add   edx, '0'         ; Add '0' to make it into character
    push  edx
    test  eax, eax         ; If EAX (the quotient) is not zero, loop again. 
    jnz   .a

.b: mov   eax, 4
    mov   ebx, 1
    mov   ecx, esp
    mov   edx, 1
    int   0x80
    pop   eax
    cmp   dword [esp], 10  ; Is it the sentinel ?
    jne   .b               ; No, it's a digit
    pop   eax              ; Remove sentinel

雖然不是 32 碼,但使用 DOS 顯示數字有更多關於將數字轉換為文本的信息。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM