CSC231 Exercises with conditinal jumps Solutions

From dftwiki3
Jump to: navigation, search

Exercises on Conditional Jumps

Finding the minimum

Find the minimum of 3 signed int variables a, b, and c

	section	.data
a       dd      3
b       dd      5
c       dd      1        
min     dd      0
        
	section	.text
	global	_start

_start:

;;; if a <= b:           # if1
;;;     if a <= c:       # if2
;;;         min = a      # 
;;;     else: # a > c    # else2
;;;         min = c      
;;; else: # a > b        # else1
;;;     if b >= c:       # if3
;;;         min = c
;;;     else: # b < c    # else3
;;;         min = b

        mov     eax, dword[a]
        mov     ebx, dword[b]
        mov     ecx, dword[c]
        
if1:    cmp     eax, ebx
        jg      else1
if2     cmp     eax, ecx
        jg      else2
        mov     dword[min], eax
        jmp     done
else2:  mov     dword[min], ecx
        jmp     done
else1:
if3:    cmp     ebx, ecx
        jl      else3
        mov     dword[min], ecx
        jmp     done
else3:  mov     dword[min], ebx
done:
        

Loop until overflow

Print fibonacci numbers coded as unsigned words until the result overflows. Don't print erroneous numbers!

3 Solution programs:

fib(2) = 2
fib(3) = 3
fib(4) = 5
fib(5) = 8
fib(6) = 13
fib(7) = 21
fib(8) = 34
fib(9) = 55
fib(10) = 89
fib(2) = 2
fib(3) = 3
fib(4) = 5
fib(5) = 8
fib(6) = 13
...
fib(19) = 6765
fib(20) = 10946
fib(21) = 17711
fib(22) = 28657
fib(2) = 2
fib(3) = 3
fib(4) = 5
fib(5) = 8
...
fib(43) = 701408733
fib(44) = 1134903170
fib(45) = 1836311903

All 3 programs require

Scanning an array

  • Find the largest element of a 1-dimensional array of signed double-words.
        section .data
msg1    db      "large of array = ",0
array   dd      1, 3, 10, 0, -2, 44, 10
N       equ     ($-array)/4        

        
        ;; -------------------------
        ;; code area
        ;; -------------------------
        section .text
        global  asm_main

;;; ---------------------------------------------------------
;;; main program
;;; ---------------------------------------------------------
asm_main:       

;;; largest = MOSTNEG;
;;; for ( i=0; i<N; i++ ) {
;;;     if ( array[i]>largest )
;;;         largest = array[i];
;;; 
;;; print "largest of array = ", largest

        mov     esi, 0
        mov     ebx, 0x80000000 ; most negative dword
        
for:    cmp     esi, N*4
        jge     done
        
        cmp     ebx, dword[array+esi]
        jg      next
        mov     ebx, dword[array+esi]
next:   add     esi, 4
        jmp     for
done:
        mov     eax, ebx
        call    printMax
        
        ret        

;;; ----------------------------------------------------------
;;; printMax: gets integer in eax and prints it
;;; ----------------------------------------------------------
printMax:      
        push    eax             ; save max in stack
        mov     eax, msg1        
        call    print_string    ; prints " "
        pop     eax             ; get max from stack
        call    print_int       ; print fact(i)
        call    print_nl        ; next line
        ret
  • Same question, but with unsigned double words.
For unsigned double words, then change the definition of the array (so that it does not contain negative numbers), and replace the jg next instruction by ja next instruction.

Characters and lower/upper case conversion

The program makeUpper.asm transforms all characters in a string to uppercase, but will also transform other characters that are not letters.

Modify the program so that it modifies only characters between 'a' and 'z' included.

;;; makeUpper.asm
;;; D. Thiebaut
;;;
;;; transforms a string to its uppercase equivalent
;;; (works only if the string contains only letters)
;;; 
;;;  nasm -f elf xxxx.asm
;;;  gcc -o xxxx driver.c asm_io.o xxxx.o
;;; 
%include "asm_io.inc"
        
        ;; -------------------------
        ;; data segment
        ;; -------------------------
        section .data
str1    db      "NabucoDonoSOR was king of Babylon!!!",0
STR1LEN equ     $-str1-1
MASK    equ     32
        
        section .bss
        
        ;; -------------------------
        ;; code area
        ;; -------------------------
        section .text
        global  asm_main
asm_main:       

;;;---  print the original string ---
        mov     eax,str1
        call    print_string   
        call    print_nl

;;;---  force characters to uppercase ---
        mov     ebx,str1
        mov     ecx,STR1LEN
        mov     ah, MASK
        not     ah
for:    mov     al, byte[ebx]
        cmp     al, 'a'
        jb      next
        cmp     al, 'z'
        ja      next
        and     byte[ebx], ah
next:
        inc     ebx
        loop    for

;;;---  print new string ---
        mov     eax,str1
        call    print_string   
        call    print_nl
        
        
        ;; return to C program

        ret

Long/short jumps

Conditional jumps can jump only +127 bytes down, -128 bytes up in the code. How can we code something like this:

                 cmp     eax,10
                 jl      there
                 ...
                 ...
        there:   ...


when the instruction at Label there is 1000 bytes away from the jl conditional jump?


                  cmp     eax,10
                  jge      next
                  jmp     there
         next:
                  ...
                  ...
         there:   ...


Print 2-dimensional arrays

Write the code necessary for printing an array of chars (maze) using for-loops depending on i and j indexes.

;;;  ------------------------------------------------------------
;;;  data areas
;;;  ------------------------------------------------------------

        section .data
maze    db "################################"     
maze2   db "            #  #           #    "     
        db "#########   #  #  #######  #   #"
        db "#           #  #        #      #"
        db "#########         ##############"
        db "#           ####               #"
        db "################################"
width   equ maze2-maze  ; num of columns
height  equ 7           ; num of rows

i        dd          0
j        dd          0


A solution...

;;; -----------------------------------------------------------------------
        ;; printMaze: prints the maze in the maze variable
        ;; Nothing needs to be passed
;;; -----------------------------------------------------------------------
printMaze:
initfori1:
        mov     dword[i],0              ;Start at 1st row
        mov     ecx,height              ;Loop once for each row
fori1:  push    ecx                     ;Store loop counter
intiforj1:
        mov     dword[j],0              ;1st column
        mov     ecx,width               ;Loop once for each column
forj1:
        push    ecx
        ;; Get ready to call offset fn
        mov     eax, [i]
        mov     ebx, [j]
        call    ijoffset
        mov     al, byte[maze+eax]      ;Get correct character in maze
        call    print_char
        inc     dword[j]                ;go to next column
        pop     ecx                     ;Retrieve loop counter
        loop    forj1

        call    print_nl
        pop     ecx
        inc     dword[i]                ;next row
        loop    fori1
        ret

;;; -----------------------------------------------------------------------
;;  ijoffset: gets a coordinate in the maze, taking the row # from eax
;;               and the column # from ebx, and calculates the
;;               appropriate offset and stores it in eax.
;;       uses eax, ebx, ecx
;;; -----------------------------------------------------------------------

ijoffset:
        mov    ecx, width              ;Number of columns
        mul     ecx                     ;eax<-row # * number of columns
        add     eax,ebx                 ;eax<-row# * # of columns + column #
        ret