乘以字长输入x86

时间:2014-11-23 03:54:43

标签: assembly x86 word

有人可以给我看一个代码,用于乘以两个WORD-SIZE数字。我一直在各地搜索,我已经尝试了所有的东西,但它会导致分段错误,错误的结果,或者不超过256.

所有变量都是字大小的,重新开始。

mov ah, 0
mov al, [num2]
mov bl, 10
mul bl                  
add al, [num1]      

mov word[num1], ax

这个结果不超过256。

mov ax, 10
mul word[num2]
add [num1], ax

这会导致分段错误,或者可能只是错误的结果,我不确定。

修改

这是我的整个代码

section .data 
    number db 'Enter a number: '
    numberLen equ $-number
    fibo db' -----Fibonacci Sequence----- ', 10
    fibolen equ $-fibo
    newline db '', 10
    newlinelen equ $-newline
    space db ' '
    spacelen equ $-space
section .bss
    num1 resw 1
    num2 resw 1
    no1 resw 1
    no2 resw 1
    no3 resw 1
section .text
    global _start

_start:
    mov eax, 4
    mov ebx, 1
    mov ecx, number
    mov edx, numberLen
    int 80h

    mov eax, 3
    mov ebx, 0
    mov ecx, num2
    mov edx, 1
    int 80h

    mov eax, 3
    mov ebx, 0
    mov ecx, num1
    mov edx, 2
    int 80h

    sub word[num1], 30h
    sub byte[num2], 30h

    mov ah,0
    mov al,[num2]
    mov bl,10
    mul bl
    add al,[num1]
    mov word[num1],ax

    mov eax, 4
    mov ebx, 1
    mov ecx, fibo
    mov edx, fibolen
    int 80h

    cmp word[num1], 0
    je skip

    sub esp, 4
    push word[num1]
    call getfibo
    pop cx
    pop dx

    skip:
        mov eax, 4
        mov ebx, 1
        mov ecx, newline
        mov edx, newlinelen
        int 80h

    exit:
        mov eax, 1
        mov ebx, 0
        int 80h

    getfibo:
        mov ebp, esp

        cmp word[ebp + 4], 1
        je fibo_end

        mov cx, [ebp+4]
        dec cx
        sub esp, 4
        push cx
        call getfibo

        pop cx
        pop dx
        mov ebp, esp

        add cx, dx
        mov word[ebp + 6], dx
        mov word[ebp + 8], cx

        mov ax, word[ebp + 8]
        mov dx, 0
        mov ah, 0
        mov bx, 100
        div bx
        mov [no3], ax
        mov [no2], dx
        mov ax, [no2]
        mov dx, 0
        mov ah, 0
        mov bx, 10
        div bx
        mov [no2], ax
        mov [no1], dx
        add word[no3], 30h
        add word[no2], 30h
        add word[no1], 30h

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

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

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

        mov eax, 4
        mov ebx, 1
        mov ecx, space
        mov edx, spacelen
        int 80h

        ret 2
        fibo_end:
            mov word[ebp + 6], 1
            mov word[ebp + 8], 1
            mov ax, word[ebp + 8]
            mov dx, 0
            mov ah, 0
            mov bx, 100
            div bx
            mov [no3], ax
            mov [no2], dx
            mov ax, [no2]
            mov dx, 0
            mov ah, 0
            mov bx, 10
            div bx
            mov [no2], ax
            mov [no1], dx
            add word[no3], 30h
            add word[no2], 30h
            add word[no1], 30h

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

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

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

            mov eax, 4
            mov ebx, 1
            mov ecx, space
            mov edx, spacelen
            int 80h

            ret 2

它显示了斐波纳契序列,数字输入决定了序列的显示数量。我遇到麻烦的部分就是这两部分。

    add cx, dx
    mov word[ebp + 6], dx
    mov word[ebp + 8], cx


    mov ah,0
    mov al,[num2]
    mov bl,10
    mul bl
    add al,[num1]
    mov word[num1],ax

现在,它不超过256,当我输入12时,它会上升到233,但是当我输入13时,它从233开始,然后是121.

1 个答案:

答案 0 :(得分:1)

您的第一个示例中似乎有一个错误。 mul bl指令的结果将是AX寄存器中的字大小结果。但是,您将内存地址num1的值添加到AL寄存器。如果加法导致进位(即使AL滚动超过255),那将会弄乱你的结果。例如,考虑[num2]是否包含30.然后,mul bl指令的结果将是AX寄存器中的值300(0x012C)。如果[num1]处的值等于212(0xD4),则add al,[num1]指令的结果将为(0x100),因为您正在进行8位加法。但结果应为 0x200。

您似乎正在尝试将两个8位值相乘以获得16位结果,并将该结果添加到[num1]处的值。正确的代码是:

mov ah,0
mov al,[num2]
mov bl,10
mul bl
add ax,[num1]
mov [num1],ax

您可以将其简化为:

mov ax,10
mul byte [num2]
add [num1],ax

可能你的第二个例子是什么意思。你的第二个例子有mul word[num2],如果将num2定义为一个字节的值,这将是一个问题(给你一个错误的结果)。如果[num2]之后的字节超出了进程的有效内存空间,可以给你一个分段错误。

评论后更新

当您将两个字大小的值相乘时,结果为双字。低位字存储在AX中,高位字存储在DX中。但如果您只关心低字,那么您可以忽略DX中的值。

您在第二个示例中所拥有的内容与此C代码相同:

int num1, num2;

num1 = num1 + (num2 * 10);

如果您真正想要的是:

num1 = num2 * 10;

然后您需要将add [num],ax更改为mov [num],ax