簡體   English   中英

如何在x86 linux nasm程序集中將2個不同長度的數字相加

[英]How to add 2 numbers together that are of different lengths in x86 linux nasm assembly

我對組裝非常陌生,並且在使用不同長度的數字進行基本計算方面遇到困難。

所以這是我的添加代碼,適用於長度為 3 個或更少字符的數字。 只要兩者長度相同。 例如 123 + 123 工作得很好並輸出 246。但 12 + 123 不起作用,它輸出 253 作為答案。 我如何才能使用不同的長度數字來實現這一點?

    sys_exit equ 1
    sys_read equ 3
    sys_write equ 4
    stdin equ 0
    stdout equ 1

    section .data
        newLine db 10
        cquestion db 'Enter a number: ', 0xa
        cqLen equ $ - cquestion

        answer db 'Your answer is: '
        aLen equ $ - answer


    section .bss

        number1 resb 4
        number2 resb 4
        number1Len resd 1
        number2Len resd 1

        answ resb 8

    %macro write_string 2
        mov eax, 4
        mov ebx, 1
        mov ecx, %1
        mov edx, %2
        int 0x80
    %endmacro

    section .text
    global _start
    _start:
    write_string cquestion, cqLen

    mov eax, sys_read
    mov ebx, stdin
    mov ecx, number1
    mov edx, 4
    int 0x80
    mov [number1Len], eax

    write_string cquestion, cqLen

    mov eax, sys_read
    mov ebx, stdin
    mov ecx, number2
    mov edx, 4
    int 0x80
    mov [number2Len], eax

    write_string answer, aLen

    clc
    mov ecx, [number2Len]           ;number of digits
    dec ecx                         ;need to decrease one for some reason?
    mov esi, ecx                
    dec esi                         ;pointing to the rightmost digit.
    .add_loop:

        mov al, [number1 + esi]
        adc al, [number2 + esi]
        aaa
        pushf               ; also no idea what this is here for
        or  al, 30h         ; or this
        popf                ; and this...

        mov [answ + esi], al
        dec esi
        loop addition.add_loop

        mov eax, sys_write
        mov ebx, stdout
        mov ecx, answ
        mov edx, 8
        int 0x80
        
        mov eax, sys_write
        mov ebx, stdout
        mov ecx, newLine
        mov edx, 1
        int 0x80

    mov [answ], DWORD 0
  • 你的循環永遠不會超過 3 次迭代。 如果有最后的進位,您將需要額外寫入目的地。
  • 如果代碼需要處理不同長度的輸入,則不能使用相同的偏移量ESI來尋址兩個數字的相應數字。
  • 您也不能使用相同的ESI來存儲輸出,因為您可能需要在左側多一個位置。
  • 關於answ resb 8 ,將幾個 3 位數字相加最多可以產生 4 位數字和。

下面是這個問題的眾多解決方案之一 雖然前面加零的答案有點難看,但至少添加是正確的!

                         ECX=1
                         v
num1:  31 32 0A 00      31 32 30 30
num2:  31 32 33 0A      31 32 33 30
                            ^
                            EDX=2

answ:                   00 00 00 00     --> 30 31 33 35
                                 ^
                                 EDI=3
    mov   ecx, [number1Len]           ; Number of bytes
    sub   ecx, 2                      ; Offset to 'ones' digit
    mov   eax, ecx                    ; Offset to the newline
  .more1:
    inc   eax
    mov   byte [number1 + eax], "0"
    test  eax, 3
    jnz   .more1


    mov   edx, [number2Len]           ; Number of bytes
    sub   edx, 2                      ; Offset to 'ones' digit
    mov   eax, ecx                    ; Offset to the newline
  .more2:
    inc   eax
    mov   byte [number2 + eax], "0"
    test  eax, 3
    jnz   .more2

    mov   edi, 3                      ; 4 iterations
    clc
  .add_loop:
    movzx eax, byte [number1 + ecx]
    lea   eax, [eax - 48]             ; From ASCII to number
    adc   al, [number2 + edx]
    mov   [answ + edi], al
    pushf                             ; Because `AND` clears the CF
    dec   ecx
    and   ecx, 3                      ; Wraparound in number1
    dec   edx
    and   edx, 3                      ; Wraparound in number2
    popf
    dec   edi
    jns   addition.add_loop

暫無
暫無

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

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