0

2 桁または 3 桁の数字になるようにバインドされている 2 つの 2 桁の数字を追加しようとしています。

これが私がこれまでに持っているものです。キャリーを印刷しようとすると、浮動小数点例外(コアダンプ)と表示されます

section .data
    msg db "Enter 2 numbers: "
    msgLen equ $-msg

section .bss
    numa1 resb 1
    numa2 resb 1
    numb1 resb 1
    numb2 resb 1
    carry resb 1

section .text
    global _start

_start: 
    ;print message
    mov eax, 4
    mov ebx, 1
    mov ecx, msg
    mov edx, msgLen
    int 80h

    ;accept first number (1st digit)
    mov eax, 3
    mov ebx, 0
    mov ecx, numa1
    mov edx, 1
    int 80h

    ;accept first number (2nd digit)
    mov eax, 3
    mov ebx, 0
    mov ecx, numa2
    mov edx, 2
    int 80h

    ;accept second number (1st digit)
    mov eax, 3
    mov ebx, 0
    mov ecx, numb1
    mov edx, 1
    int 80h

    ;accept second number (2nd digit)
    mov eax, 3
    mov ebx, 0
    mov ecx, numb2
    mov edx, 2
    int 80h

    ;character to number conversion
    sub byte[numa1], 30h
    sub byte[numa2], 30h
    sub byte[numb1], 30h
    sub byte[numb2], 30h
    sub byte[carry], 30h

    ;;;;;;;;;;;;;;;;;;;;;;;;;;

    ;add ones digit
    mov al, [numa2]
    add byte[numb2], al
    add byte[numb2], 30h

    ;get carry of sum of ones digit
    mov ax, [numb2]
    mov byte[carry], 10
    div byte[carry]

    mov eax, 4
    mov ebx, 1
    mov ecx, carry
    mov edx, 1
    int 80h


    mov eax, 1
    mov ebx, 0
    int 80h

  carry
  numa1   numa2
+ numb2   numb2
---------------
          numb2

where numb2 = numb2 % 10
      carry = numb2 / 10
4

2 に答える 2

1

まず、xor ebx, ebxより短くて速いmov ebx, 0

また、1 桁の数字を 2 つ足すとキャリーは最大で 1 (9 + 9 = 18) になるので、割る必要はなく、10 を引くだけで十分です。さらに、通常は 16 ビット レジスタを避ける必要があります。16 ビット レジスタは長く (66h プレフィックスのため)、低速です (部分的なレジスタ更新のため)。つまり

mov ax, [numb2]
mov byte[carry], 10
div byte[carry]

次のものよりもはるかに遅くなります

movzx eax, word ptr [numb2]
sub   eax, 10

しかし結局のところ、x86 には既にその目的のためのBCD 命令があるのに、なぜそのような複雑な方法を使用するのでしょうか。その上、それらの命令には BCD 演算用の AF と CF が含まれているため、自分で管理する必要はありません。

バイナリ演算を直接使用して、入力/出力で変換することもできます。ほとんどの場合、変換のコストはごくわずかです

于 2014-02-13T03:48:18.687 に答える