CS323 - Note 5 – Day 5 – 2/1/2006
math.asm, Mult, div, Bit ops, Simple calls

Go over sample program pS.asm  (long way to print string).)

Standard control structures à see Carter section 2.3

Multiply and divide instructions

mul – for unsigned numbers

      mul      source       ;  source is register or memory

                            ;  if size of source == 1 byte; ax <- al * source

                            ;  if size of source == 2 bytes; dx:ax <- ax * source

                            ;  if size of source == 4 bytes; edx:eax <- eax * source

 

imul – for signed numbers

      imul      source       ;  source is register or memory, OR

      imul      dest, source1

      imul      dest, source1, source2  ; see Table 2.2 for meanings

 

Note that the following figures were taken from nasmdoc.pdf

Math.asm – show redirecting input and output on IO

; file: math.asm
; This program demonstrates how the integer multiplication and division
; instructions work.
;
; To create executable:
; nasm -f elf math.asm
; gcc -o math math.o driver.c asm_io.o
%include "asm_io.inc"
segment .data
;
; Output strings
;
prompt          db    "Enter a number: ", 0
square_msg      db    "Square of input is ", 0
cube_msg        db    "Cube of input is ", 0
cube25_msg      db    "Cube of input times 25 is ", 0
quot_msg        db    "Quotient of cube/100 is ", 0
rem_msg         db    "Remainder of cube/100 is ", 0
neg_msg         db    "The negation of the remainder is ", 0

segment .bss
input   resd 1
segment .text
        global  asm_main
asm_main:
        enter   0,0               ; setup routine
        pusha

        mov     eax, prompt
        call    print_string

        call    read_int
        mov     [input], eax

        imul    eax               ; edx:eax = eax * eax
        mov     ebx, eax          ; save answer in ebx
        mov     eax, square_msg
        call    print_string
        mov     eax, ebx
        call    print_int
        call    print_nl

        mov     ebx, eax
        imul    ebx, [input]      ; ebx *= [input]
        mov     eax, cube_msg
        call    print_string
        mov     eax, ebx
        call    print_int
        call    print_nl

        imul    ecx, ebx, 25      ; ecx = ebx*25
        mov     eax, cube25_msg
        call    print_string
        mov     eax, ecx
        call    print_int
        call    print_nl

        mov     eax, ebx
        cdq                       ; initialize edx by sign extension
        mov     ecx, 100          ; can't divide by immediate value
        idiv    ecx               ; edx:eax / ecx
        mov     ecx, eax          ; save quotient into ecx
        mov     eax, quot_msg
        call    print_string
        mov     eax, ecx
        call    print_int
        call    print_nl
        mov     eax, rem_msg
        call    print_string
        mov     eax, edx
        call    print_int
        call    print_nl
       
        neg     edx               ; negate the remainder
        mov     eax, neg_msg
        call    print_string
        mov     eax, edx
        call    print_int
        call    print_nl

        popa
        mov     eax, 0            ; return back to C
        leave                    
        ret

 

Sample output using 34 for input

Enter a number: 34

Square of input is 1156
Cube of input is 39304
Cube of input times 25 is 982600
Quotient of cube/100 is 393
Remainder of cube/100 is 4
The negation of the remainder is -4

Bit ops (Time permitting)

Discuss shl, shr, sal, sar, and, or (Chapter 3 in the Carter text)

Simple calls (Time permitting)

For program mp20, parameter passing is via registers as documented in the program description.

Function is defined as:

 

funcName:

 

        ;  put code for function

 

        ret      ; this is the return to the caller

Extended precision arithmetic

Note: Instructions: add & sub modify the carry flag if a carry or borrow occur, respectively.

 

ADC   :   operand1 <- operand1 + CF + operand2

 

SBB   :   operand1 <- operand1 - CF - operand2

 

Suppose we want to add 64-bit integers:  EDX:EAX <- EDX:EAX + EBX:ECX

 

      Add    eax, ecx    : add lower 32 bits

      Adc    edx, ebx    ; add upper 32 bits & carry flag from previous sum