CSC231 Exercises with conditinal jumps Solutions
Exercises on Conditional Jumps
Contents
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:
- FibOverflowByte.asm: using an array of bytes
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
- FibOverflowWord.asm: using an array of words
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
- FibOverflowDWord.asm: using an array of dwords
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