Colin James Naranjo
Colin James Naranjo

Reputation: 1

Multiplying word size inputs x86

can someone please show me a code for multiplying two WORD-SIZE digits. I've been searching everywhere and i've tried everything but it either results in a segmentation fault, wrong result, or not exceeding 256.

All of the variables are word-size, resw.

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

mov word[num1], ax

This one results to not exceeding 256.

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

This one results to a segmentation fault, or probably just a wrong result, i'm not sure.

EDIT

Here's my whole code

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

It shows the fibonacci sequence, the number input determines how many of the sequence will show up. The parts that I'm having trouble are these two.

    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

For now, it's not exceeding 256, When I input 12, it goes up to 233, but when i input 13, it goes from 233, then 121.

Upvotes: 0

Views: 674

Answers (1)

Jim Mischel
Jim Mischel

Reputation: 134055

It seems like you have a bug in your first example. The result of the mul bl instruction will be a word-sized result in the AX register. But then you add the value at memory address num1 to the AL register. That's going to mess up your result if the addition results in a carry (i.e. makes AL roll past 255). Consider, for example, if the [num2] contains 30. The result of the mul bl instruction, then, will be a value of 300 (0x012C) in the AX register. If the value at [num1] is equal to 212 (0xD4), then the result of the add al,[num1] instruction will be (0x100), because you're doing an 8-bit addition. But the result should be 0x200.

It appears you're trying to multiply two 8-bit values to get a 16-bit result, and add that result to the value at [num1]. The correct code would be:

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

You can simplify that to:

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

Which is probably what you meant to do with your second example. Your second example has mul word[num2], which is going to be a problem (give you a wrong result) if num2 is defined as a one-byte value. It could give you a segmentation fault if the byte after [num2] is outside your process's valid memory space.

Update after comment

When you multiply two word-sized values, the result is a dword. The low word is stored in AX, and the high word is in DX. But if you just care about the low word, then you can ignore the value in DX.

What you have in your second example is equivalent to this C code:

int num1, num2;

num1 = num1 + (num2 * 10);

If what you really want is:

num1 = num2 * 10;

Then you need to change that add [num],ax to mov [num],ax.

Upvotes: 1

Related Questions