0

我正在尝试添加 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, ebxmov ebx, 0

此外,两个 1 位数字相加的最大进位为 1 (9 + 9 = 18),因此无需除法,只需将数字减去 10 即可。此外,您通常应该避免使用 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 回答
0

请注意“浮点异常”,但这些行可能会导致除法溢出:

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

你正在做一个单词 move from numb2to ax,这意味着你会得到任何存储carryah. 如果我们假设该.bss部分在启动时归零,则值 atcarry将是0xD0您将其加载到 时ah,因为您已经完成了sub byte[carry], 30h.

因此,您要除以0xD0nn10,这将导致商太大而无法放入al.

你可以mov ax, [numb2]movzx ax,byte [numb2].

于 2013-06-24T07:01:50.560 回答