Difference between revisions of "CSC231 Exercises with conditinal jumps Solutions"

From dftwiki3
Jump to: navigation, search
(Loop until overflow)
(Print 2-dimensional arrays)
 
(7 intermediate revisions by the same user not shown)
Line 99: Line 99:
 
==Scanning an array==
 
==Scanning an array==
  
Find the '''largest''' element of a 1-dimensional array of '''signed double-words'''.  
+
* Find the '''largest''' element of a 1-dimensional array of '''signed double-words'''.  
  
Same question, but with  '''unsigned double words'''.
+
<code><pre>
 +
        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
 +
</pre></code>
 +
 +
* 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==
 
==Characters and lower/upper case conversion==
Line 109: Line 165:
  
 
Modify the program so that it modifies only characters between 'a' and 'z' included.
 
Modify the program so that it modifies only characters between 'a' and 'z' included.
 +
 +
<code><pre>
 +
;;; 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
 +
 +
</pre></code>
  
 
==Long/short jumps==
 
==Long/short jumps==
Line 122: Line 239:
 
        
 
        
 
when the instruction at Label ''there'' is 1000 bytes away from the jl conditional jump?
 
when the instruction at Label ''there'' is 1000 bytes away from the jl conditional jump?
 +
 +
<code><pre>
 +
 +
                  cmp    eax,10
 +
                  jge      next
 +
                  jmp    there
 +
        next:
 +
                  ...
 +
                  ...
 +
        there:  ...
 +
 +
 +
</pre></code>
  
 
==Print 2-dimensional arrays==
 
==Print 2-dimensional arrays==
Line 139: Line 269:
 
         db "#          ####              #"
 
         db "#          ####              #"
 
         db "################################"
 
         db "################################"
C      equ maze2-maze  ; num of columns
+
width  equ maze2-maze  ; num of columns
R      equ 7          ; num of rows
+
height  equ 7          ; num of rows
  
 
i        dd          0
 
i        dd          0
 
j        dd          0
 
j        dd          0
 +
</pre></code>
 +
 +
 +
A solution...
 +
 +
<code><pre>
 +
;;; -----------------------------------------------------------------------
 +
        ;; 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
 +
 +
 
</pre></code>
 
</pre></code>

Latest revision as of 09:45, 29 October 2008

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