Star InactiveStar InactiveStar InactiveStar InactiveStar Inactive
 
main.cpp
#include <stdio.h>

extern "C" int IntegerMulDiv(int a, int b, int* prod, int* quo, int* rem);

int main(int argc, char *argv[])
{
    int a = 21, b = 9;
    int prod = 0, quo = 0, rem = 0;
    int rc;
    
    rc = IntegerMulDiv(a, b, &prod, &quo, &rem);
    printf(" Input1 - a:   %4d  b:    %4d\n", a, b);
    printf("Output1 - rc:  %4d  prod: %4d\n", rc, prod);
    printf("          quo: %4d  rem:  %4d\n\n", quo, rem);
    
    a = -29;
    prod = quo = rem = 0;
    rc = IntegerMulDiv(a, b, &prod, &quo, &rem);
    printf(" Input2 - a:   %4d  b:    %4d\n", a, b);
    printf("Output2 - rc:  %4d  prod: %4d\n", rc, prod);
    printf("          quo: %4d  rem:  %4d\n\n", quo, rem);
    
    b = 0;
    prod = quo = rem = 0;
    rc = IntegerMulDiv(a, b, &prod, &quo, &rem);
    printf(" Input3 - a:   %4d  b:    %4d\n", a, b);
    printf("Output3 - rc:  %4d  prod: %4d\n", rc, prod);
    printf("          quo: %4d  rem:  %4d\n\n", quo, rem);
    return 0;
    
}
integermuldiv.asm
; Name:     integermuldiv.asm
;
; Build:    g++ -m32 -c main.cpp -o main.o
;           nasm -f elf32 -o integermuldiv.o integermuldiv.asm
;           g++ -m32 -o integermuldiv integermuldiv.o main.o
;
; Source:   Modern x86 Assembly Language Programming p.33

global  IntegerMulDiv

section .text

; extern "C" int IntegerMulDiv(int a, int b, int* prod, int* quo, int* rem);
;
; Description:  This function demonstrates use of the imul and idiv
;               instructions.  It also illustrates pointer usage.
;
; Returns:      0   Error (divisor is zero)
;               1   Success (divisor is zero)
;
; Computes:     *prod = a * b;
;               *quo = a / b
;               *rem = a % b

%define a       [ebp+8]
%define b       [ebp+12]
%define prod    [ebp+16]
%define quo     [ebp+20]
%define rem     [ebp+24]

IntegerMulDiv:
    push    ebp
    mov     ebp, esp
    push    ebx
    push    ecx
    xor     eax, eax
    mov     ebx, b
    or      ebx, ebx            ; b = 0 ?
    jz      .invalidDivisor
    mov     eax, a
    imul    eax, ebx            ; prod = a * b
    mov     ecx, prod
    mov     [ecx], eax          ; save product
    mov     eax, a
    cdq
    mov     ebx, b
    idiv    ebx                 ; quo = a / b in eax, rem = a % b in edx
    mov     ecx, quo
    mov     [ecx], eax          ; save quotient
    mov     ecx, rem
    mov     [ecx], edx          ; save remainder
    mov     eax, 1              ; rc = 1 = succes
.invalidDivisor:
    ; rax = 0 when b is zero
    pop     ecx
    pop     ebx
    pop     ebp
    ret
build
g++ -m32 -c main.cpp -o main.o
nasm -f elf32 -o integermuldiv.o integermuldiv.asm
g++ -m32 -o integermuldiv integermuldiv.o main.o