Lab5: Control and Loops
1. Objectives: after completing this lab, learner will be able to:
2. Prerequest
 - review the theory of assembly language
3. Tools
 - Computer with installed softwares
4. Duration
 - 4 hours
5. Contents:
 5.1. Introduction
 Program control refers to basic programming structures such as IF statements and
 looping.
 All of the high-level language control structures must be performed with the limited
 assembly language control structures. For example, an IF-THEN-ELSE statement
 does not exist at the assembly language level. Assembly language provides an
 unconditional branch (or jump) and a conditional branch or an IF statement that will
 jump to a target label or not jump.
 The control instructions refer to unconditional and conditional jumping. Jumping is
 required for basic conditional statements (i.e., IF statements) and looping.
 5.1.1. Label
 A program label is the target, or a location to jump to, for control statements. For
 example, the start of a loop might be marked with a label such as “loopStart”. The
 code may be re-executed by jumping to the label.
 Generally, a label starts with a letter, followed by letters, numbers, or symbols
 (limited to “_”), terminated with a colon (“:”). It is possible to start labels with non-
 letter characters (i.e., digits, “_”, “$”, “#”, “@”, “~” or “?”) . However, these typically
 convey special meaning and, in general, should not be used by programmers
For example,
 loopStart:
 last:
 5.1.2. Unconditional Control Instructions
 Pages - 1
Computer architecture labs
 The unconditional instruction provides an unconditional jump to a specific location
 in the program denoted with a program label. The target label must be defined
 exactly once and accessible and within scope from the originating jump instruction.
The unconditional jump instruction is summarized as follows:
 Instruction Explanation
 Jump to specified label.
 jmp <label>
 Note, label must be defined exactly once.
 jmp startLoop
 Examples: jmp ifDone
 jmp last
 5.1.3. Conditional Control Instructions
 The conditional control instructions provide a conditional jump based on a
 comparison. This provides the functionality of a basic IF statement.
 Two steps are required for a comparison; the compare instruction and the
 conditional jump instruction. The conditional jump instruction will jump or not jump
 to the
 cmp <op1>, <op2>
 loop <label>
 je <label> ; if <op1> == <op2>
 jne <label> ; if <op1> != <op2>
 jl <label> ; signed, if <op1> < <op2>
 jle <label> ; signed, if <op1> <= <op2>
 jg <label> ; signed, if <op1> > <op2>
 jge <label> ; signed, if <op1> >= <op2>
 jb <label> ; unsigned, if <op1> < <op2>
 Pages - 2
Computer architecture labs
 jbe <label> ; unsigned, if <op1> <= <op2>
 ja <label> ; unsigned, if <op1> > <op2>
 jae <label> ; unsigned, if <op1> >= <op2>
 5.2.
6. Examples
 6.1. Example 1: Loop example (lab51.nasm)
;Betterloop.asm
;;; An example of the loop and jcxz instructions
SYS_EXIT equ 60
section .data
 output db `The value is: %d\n`,0
section .text
global _start
extern printf
_start:
 mov rcx,0
 mov rsi,0
 jrcxz done
loop1:
 add rsi,rcx
 loop loop1
done:
 mov rdi,output
 mov rax,0
 call printf
 mov rdi,0
 mov eax,SYS_EXIT
 syscall
;;; *EOF*
 ✓ Compile and run program
 ✓ nasm -o lab51.o -felf64 lab51.nasm
 ✓ ld -dynamic-linker /lib64/ld-linux-x86-64.so.2 -o lab51 lab51.o -lc
 ✓ ./lab51
 ✓ The value is: 0
 6.2. Example 2: Call test (lab52.nasm)
;Calltest.asm
;;; An example of using the CALL instruction
section .data
 output db `This is section %d\n`,0
section .text
global _start
extern exit,printf
_start:
 Pages - 3
Computer architecture labs
 mov rsi,1
 mov rdi,output
 mov rax,0
 call printf
 call overhere
 mov rsi,3
 mov rdi,output
 mov rax,0
 call printf
 mov rdi,0
 call exit
overhere:
 mov rsi,2
 mov rdi,output
 mov rax,0
 call printf
 ret
;;; *EOF*
 ✓ Compile and run program
 ✓ nasm -o lab52.o -felf64 lab52.nasm
 ✓ ld -dynamic-linker /lib64/ld-linux-x86-64.so.2 -o lab52 lab52.o -lc
 ✓ ./lab52
 ✓ This is section 1
 ✓ This is section 2
 ✓ This is section 3
 6.3. Example 3: Cmp example test
Cmptest.asm
;;; An example of using the CMP and JGE instructions
SYS_EXIT equ 60
section .text
global _start
_start:
 nop
 mov rax,15
 mov rdi,10
 cmp rdi,rax
 jge greater
 mov eax,SYS_EXIT
 syscall
greater:
 mov eax,SYS_EXIT
 mov rdi,20
 syscall
;;; *EOF*
 6.4. Example 4: Jmp example test
 Pages - 4
Computer architecture labs
Jumptest.asm
;;; An example of the jmp instruction
SYS_EXIT equ 60
section .text
global _start
_start:
 nop
 mov eax,1
 jmp overhere
 mov rdi,10
 mov eax,SYS_EXIT
 syscall
overhere:
 mov rdi,20
 mov eax,SYS_EXIT
 syscall
;;; *EOF*
 6.5. Example 5: Loop example test
Loop.asm
;;; An example of the loop instruction
SYS_EXIT equ 60
section .data
output:
 db `The value is: %d\n`,0
section .text
global _start
extern printf
_start:
 mov rcx,100
 mov rsi,0
loop1:
 add rsi,rcx
 loop loop1
 mov rdi,output
 mov rax,0
 call printf
 mov rdi,0
 mov eax,SYS_EXIT
 syscall
;;; *EOF*
 6.6. Example 6: Parity example test
Paritytest.asm
;;; An example of testing the parity flag
SYS_EXIT equ 60
section .text
global _start
 Pages - 5
Computer architecture labs
_start:
 mov rax,1
 mov rdi,4
 sub rdi,3
 jp overhere
 mov eax,SYS_EXIT
 syscall
overhere:
 mov rdi,100
 mov eax,SYS_EXIT
 syscall
;;; *EOF*
 6.7. Example 7: Sign example test
Signtest.asm
;;; An example of using the sign flag
SYS_EXIT equ 60
section .data
value:
 dq 21, 15, 34, 11, 6, 50, 32, 80, 10, 2
output:
 db `The value is: %d\n`,0
section .text
global _start
extern printf
_start:
 mov rcx,9
loop:
 push rcx ;***
 mov rsi,[value + rcx * 8]
 mov rdi,output
 mov rax,0
 call printf
 pop rcx ;***
 dec rcx
 jns loop
 mov rdi,0
 mov eax,SYS_EXIT
 syscall
;;; *EOF*
 6.8. Example 8
 Command Line Arguments
 You know that in C, main is just a plain old function, and it has a couple parameters of its
 own: int main(int argc, char** argv)
 Pages - 6
Computer architecture labs
 So, you guessed it, argc will end up in rdi, and argv (a pointer) will end up in rsi. Here is a
 program that uses this fact to simply echo the command line arguments to a program,
 one per line: echo.asm program
 ; -----------------------------------------------------------------------------
 ; A 64-bit program that displays its command line arguments, one per line.
 ; On entry, rdi will contain argc and rsi will contain argv.
 ; -----------------------------------------------------------------------------
 global main
 extern puts
 section .text
 main:
 push rdi ; save registers that puts uses
 push rsi
 sub rsp, 8 ; must align stack before call
 mov rdi, [rsi] ; the argument string to display
 call puts ; print it
 add rsp, 8 ; restore %rsp to pre-aligned value
 pop rsi ; restore registers puts used
 pop rdi
 add rsi, 8 ; point to next argument
 dec rdi ; count down
 jnz main ; if not done counting keep going
 ret
 compile and run
 $ nasm -felf64 echo.asm && gcc echo.o && ./a.out dog 22 -zzz "hi there"
 ./a.out
 dog
 22
 -zzz
 hi there
 6.9. Example 9
Write the source code and save as jump.asm. Next assemble, link and run this program.
; jump.asm
extern printf
global main
section .data
 number1 dq 42
 number2 dq 41
 fmt1 db "NUMBER1 > = NUMBER2",10,0
 fmt2 db "NUMBER1 < NUMBER2",10,0
 Pages - 7
Computer architecture labs
section .bss
section .text
main:
 push rbp
 mov rbp,rsp
 mov rax, [number1] ; move the numbers into registers
 mov rbx, [number2]
 cmp rax,rbx ; compare rax and rbx
 jge greater ; rax greater or equal go to greater:
 mov rcx,fmt2 ; rax is smaller, continue here
 call printf ; display fmt2
 jmp exit
greater:
 mov rcx,fmt1 ; rax is greater
 call printf ; display fmt1
exit:
 mov rsp,rbp
 pop rbp
 ret
 6.10. Example 10
Write a program to display the sum of numbers 1 to 10.
; jumploop.asm
extern printf
section .data
 number dq 10
 fmt db "The sum from 0 is %i",10,0
section .bss
section .text
global main
main:
 push rbp
 mov rbp, rsp
 mov rbx,0 ; counter
 mov rax,0 ; sum will be in rax
jloop:
 add rax, rbx
 inc rbx
 cmp rbx,[number] ; number already reached?
 jle jloop ; number not reached yet, loop
 ; number reached, continue here
 mov rcx,fmt ; prepare for displaying
 mov rdx, rax
 call printf
 mov rsp,rbp
 pop rbp
 Pages - 8
Computer architecture labs
 ret
 6.11. Example 11
 Note that as far as the C Library is concerned, command line arguments are always
 strings. If you want to treat them as integers, call atoi. Here’s a neat program to
 compute xy
 power.asm
 ; -----------------------------------------------------------------------------
 ; A 64-bit command line application to compute x^y.
 ; Syntax: power x y
 ; x and y are (32-bit) integers
 ; -----------------------------------------------------------------------------
 global main
 extern printf
 extern puts
 extern atoi
 section .text
 main:
 push r12 ; save callee-save registers
 push r13
 push r14
 ; By pushing 3 registers our stack is already aligned for calls
 cmp rdi, 3 ; must have exactly two arguments
 jne error1
 mov r12, rsi ; argv
 ; We will use ecx to count down form the exponent to zero, esi to hold the
 ; value of the base, and eax to hold the running product.
 mov rdi, [r12+16] ; argv[2]
 call atoi ; y in eax
 cmp eax, 0 ; disallow negative exponents
 jl error2
 mov r13d, eax ; y in r13d
 mov rdi, [r12+8] ; argv
 call atoi ; x in eax
 mov r14d, eax ; x in r14d
 mov eax, 1 ; start with answer = 1
 check:
 test r13d, r13d ; we're counting y downto 0
 jz gotit ; done
 imul eax, r14d ; multiply in another x
 dec r13d
 jmp check
 gotit: ; print report on success
 Pages - 9
Computer architecture labs
 mov rdi, answer
 movsxd rsi, eax
 xor rax, rax
 call printf
 jmp done
 error1: ; print error message
 mov edi, badArgumentCount
 call puts
 jmp done
 error2: ; print error message
 mov edi, negativeExponent
 call puts
 done: ; restore saved registers
 pop r14
 pop r13
 pop r12
 ret
 answer:
 db "%d", 10, 0
 badArgumentCount:
 db "Requires exactly two arguments", 10, 0
 negativeExponent:
 db "The exponent may not be negative", 10, 0
 ✓ Compile And Run
 $ nasm -felf64 power.asm && gcc -o power power.o
 $ ./power 2 19
 524288
 $ ./power 3 -8
 The exponent may not be negative
 $ ./power 1 500
 1
 $ ./power 1
 Requires exactly two arguments
 6.12. Example 12
 Loopint_64.asm simple loop
 The nasm source code is loopint_64.asm
 The result of the assembly is loopint_64.lst
 The equivalent "C" program is loopint_64.c
 Running the program produces output loopint_64.out
 This program demonstrates basic loop assembly language
; loopint_64.asm code loopint.c for nasm
; /* loopint_64.c a very simple loop that will be coded for nasm */
 Pages - 10
Computer architecture labs
; #include <stdio.h>
; int main()
;{
; long int dd1[100]; // 100 could be 3 gigabytes
; long int i; // must be long for more than 2 gigabytes
; dd1[0]=5; /* be sure loop stays 1..98 */
; dd1[99]=9;
; for(i=1; i<99; i++) dd1[i]=7;
; printf("dd1[0]=%ld, dd1[1]=%ld, dd1[98]=%ld, dd1[99]=%ld\n",
; dd1[0], dd1[1], dd1[98],dd1[99]);
; return 0;
;}
; execution output is dd1[0]=5, dd1[1]=7, dd1[98]=7, dd1[99]=9
section .bss
 dd1: resq 100 ; reserve 100 long int
 i: resq 1 ; actually unused, kept in register
section .data ; Data section, initialized variables
 fmt: db "dd1[0]=%ld, dd1[1]=%ld, dd1[98]=%ld, dd1[99]=%ld",10,0
extern printf ; the C function, to be called
 section .text
 global main
main: push rbp ; set up stack
 mov qword [dd1],5 ; dd1[0]=5; memory to memory
 mov qword [dd1+99*8],9 ; dd1[99]=9; indexed 99 qword
 mov rdi, 1*8 ; i=1; index, will move by 8 bytes
loop1: mov qword [dd1+rdi],7 ; dd1[i]=7;
 add rdi, 8 ; i++; 8 bytes
 cmp rdi, 8*99 ; i<99
 jne loop1 ; loop until incremented i=99
 mov rdi, fmt ; pass address of format
 mov rsi, qword [dd1] ; dd1[0] first list parameter
 mov rdx, qword [dd1+1*8] ; dd1[1] second list parameter
 mov rcx, qword [dd1+98*8] ; dd1[98] third list parameter
 mov r8, qword [dd1+99*8] ; dd1[99] fourth list parameter
 mov rax, 0 ; no xmm used
 call printf ; Call C function
 pop rbp ; restore stack
 mov rax,0 ; normal, no error, return value
 ret ; return 0;
 ✓ Compile and run
 6.13. Example 13
 Shift_64.asm shifting
 Pages - 11
Computer architecture labs
 The nasm source code is shift_64.asm
 The result of the assembly is shift_64.lst
 Running the program produces output shift_64.out
 This program demonstrates basic shifting in assembly language
; shift_64.asm the nasm code is one sample, not unique
; compile: nasm -f elf64 -l shift_64.lst shift_64.asm
; link: gcc -o shift_64 shift_64.o
; run: ./shift_64 > shift_64.out
; the output from running shift.asm (zero filled) is:
; shl rax,4, old rax=ABCDEF0987654321, new rax=BCDEF09876543210,
; shl rax,8, old rax=ABCDEF0987654321, new rax=CDEF098765432100,
; shr rax,4, old rax=ABCDEF0987654321, new rax= ABCDEF098765432,
; sal rax,8, old rax=ABCDEF0987654321, new rax=CDEF098765432100,
; sar rax,4, old rax=ABCDEF0987654321, new rax=FABCDEF098765432,
; rol rax,4, old rax=ABCDEF0987654321, new rax=BCDEF0987654321A,
; ror rax,4, old rax=ABCDEF0987654321, new rax=1ABCDEF098765432,
; shld rdx,rax,8, old rdx:rax=0,ABCDEF0987654321,
; new rax=ABCDEF0987654321 rdx= AB,
; shl rax,8 ; old rdx:rax=0,ABCDEF0987654321,
; new rax=CDEF098765432100 rdx= AB,
; shrd rdx,rax,8, old rdx:rax=0,ABCDEF0987654321,
; new rax=ABCDEF0987654321 rdx=2100000000000000,
; shr rax,8 , old rdx:rax=0,ABCDEF0987654321,
; new rax= ABCDEF09876543 rdx=2100000000000000,
 extern printf ; the C function to be called
%macro prt 1 ; old and new rax
section .data
 .str db %1,0 ; %1 is which shift string
section .text
 mov rdi, fmt ; address of format string
 mov rsi, .str ; callers string
 mov rdx,rax ; new value
 mov rax, 0 ; no floating point
 call printf ; Call C function
%endmacro
%macro prt2 1 ; old and new rax,rdx
section .data
 .str db %1,0 ; %1 is which shift
section .text
 mov rdi, fmt2 ; address of format string
 mov rsi, .str ; callers string
 Pages - 12
Computer architecture labs
 mov rcx, rdx ; new rdx befor next because used
 mov rdx, rax ; new rax
 mov rax, 0 ; no floating point
 call printf ; Call C function
%endmacro
section .bss
 raxsave: resq 1 ; save rax while calling a function
 rdxsave: resq 1 ; save rdx while calling a function
section .data ; preset constants, writable
 b64: dq 0xABCDEF0987654321 ; data to shift
 fmt: db "%s, old rax=ABCDEF0987654321, new rax=%16lX, ",10,0 ; format string
fmt2: db "%s, old rdx:rax=0,ABCDEF0987654321,",10," new rax=%16lX rdx=%16lX, ",10,0
section .text ; instructions, code segment
global main ; for gcc standard linking
main: push rbp ; set up stack
shl1: mov rax, [b64] ; data to shift
 shl rax, 4 ; shift rax 4 bits, one hex position left
 prt "shl rax,4 " ; invoke the print macro
shl4: mov rax, [b64] ; data to shift
 shl rax,8 ; shift rax 8 bits. two hex positions left
 prt "shl rax,8 " ; invoke the print macro
shr4: mov rax, [b64] ; data to shift
 shr rax,4 ; shift
 prt "shr rax,4 " ; invoke the print macro
sal4: mov rax, [b64] ; data to shift
 sal rax,8 ; shift
 prt "sal rax,8 " ; invoke the print macro
sar4: mov rax, [b64] ; data to shift
 sar rax,4 ; shift
 prt "sar rax,4 " ; invoke the print macro
rol4: mov rax, [b64] ; data to shift
 rol rax,4 ; shift
 prt "rol rax,4 " ; invoke the print macro
ror4: mov rax, [b64] ; data to shift
 ror rax,4 ; shift
 prt "ror rax,4 " ; invoke the print macro
shld4: mov rax, [b64] ; data to shift
 mov rdx,0 ; register receiving bits
 shld rdx,rax,8 ; shift
 mov [raxsave],rax ; save, destroyed by function
 mov [rdxsave],rdx ; save, destroyed by function
 prt2 "shld rdx,rax,8"; invoke the print macro
shla: mov rax,[raxsave] ; restore, destroyed by function
 Pages - 13
Computer architecture labs
 mov rdx,[rdxsave] ; restore, destroyed by function
 shl rax,8 ; finish double shift, both registers
 prt2 "shl rax,8 "; invoke the print macro
shrd4: mov rax, [b64] ; data to shift
 mov rdx,0 ; register receiving bits
 shrd rdx,rax,8 ; shift
 mov [raxsave],rax ; save, destroyed by function
 mov [rdxsave],rdx ; save, destroyed by function
 prt2 "shrd rdx,rax,8"; invoke the print macro
shra: mov rax,[raxsave] ; restore, destroyed by function
 mov rdx,[rdxsave] ; restore, destroyed by function
 shr rax,8 ; finish double shift, both registers
 prt2 "shr rax,8 "; invoke the print macro
 pop rbp ; restore stack
 mov rax,0 ; exit code, 0=normal
 ret ; main returns to operating system
 6.14. Example 14
 ifint_64.asm if then else
 The nasm source code is ifint_64.asm
 The result of the assembly is ifint_64.lst
 The equivalent "C" program is ifint_64.c
 Running the program produces output ifint_64.out
 This program demonstrates basic if then else in assembly language
; ifint_64.asm code ifint_64.c for nasm
; /* ifint_64.c an 'if' statement that will be coded for nasm */
; #include <stdio.h>
; int main()
;{
; long int a=1;
; long int b=2;
; long int c=3;
; if(a<b)
; printf("true a < b \n");
; else
; printf("wrong on a < b \n");
; if(b>c)
; printf("wrong on b > c \n");
; else
; printf("false b > c \n");
; return 0;
;}
; result of executing both "C" and assembly is:
; true a < b
 Pages - 14
Computer architecture labs
; false b > c
global main ; define for linker
extern printf ; tell linker we need this C function
section .data ; Data section, initialized variables
 a: dq 1
 b: dq 2
 c: dq 3
 fmt1: db "true a < b ",10,0
 fmt2: db "wrong on a < b ",10,0
 fmt3: db "wrong on b > c ",10,0
 fmt4: db "false b > c ",10,0
section .text
main: push rbp ; set up stack
 mov rax,[a] ;a
 cmp rax,[b] ; compare a to b
 jge false1 ; choose jump to false part
 ; a < b sign is set
 mov rdi, fmt1 ; printf("true a < b \n");
 call printf
 jmp exit1 ; jump over false part
false1: ; a < b is false
 mov rdi, fmt2 ; printf("wrong on a < b \n");
 call printf
exit1: ; finished 'if' statement
 mov rax,[b] ;b
 cmp rax,[c] ; compare b to c
 jle false2 ; choose jump to false part
 ; b > c sign is not set
 mov rdi, fmt3 ; printf("wrong on b > c \n");
 call printf
 jmp exit2 ; jump over false part
false2: ; b > c is false
 mov rdi, fmt4 ; printf("false b > c \n");
 call printf
exit2: ; finished 'if' statement
 pop rbp ; restore stack
 mov rax,0 ; normal, no error, return value
 ret ; return 0;
 6.15. Example 15
 call1_64.asm change callers array
 The nasm source code is call1_64.asm
 The main "C" program is test_call1_64.c
 Be safe, header file is call1_64.h
 Pages - 15
Computer architecture labs
 The equivalent "C" program is call1_64.c
 Running the program produces output test_call1_64.out
 This program demonstrates passing an array to assembly language
 and the assembly language updating the array.
; call1_64.asm a basic structure for a subroutine to be called from "C"
; Parameter: long int *L
; Result: L[0]=L[0]+3 L[1]=L[1]+4
 global call1_64 ; linker must know name of subroutine
 extern printf ; the C function, to be called for demo
 SECTION .data ; Data section, initialized variables
 fmt1: db "rdi=%ld, L[0]=%ld", 10, 0 ; The printf format, "\n",'0'
 fmt2: db "rdi=%ld, L[1]=%ld", 10, 0 ; The printf format, "\n",'0'
SECTION .bss
 a: resq 1 ; temp for printing
SECTION .text ; Code section.
call1_64: ; name must appear as a nasm label
 push rbp ; save rbp
 mov rbp, rsp ; rbp is callers stack
 push rdx ; save registers
 push rdi
 push rsi
 mov rax,rdi ; first, only, in parameter
 mov [a],rdi ; save for later use
 mov rdi,fmt1 ; format for printf debug, demo
 mov rsi,rax ; first parameter for printf
 mov rdx,[rax] ; second parameter for printf
 mov rax,0 ; no xmm registers
 call printf ; Call C function
 mov rax,[a] ; first, only, in parameter, demo
 mov rdi,fmt2 ; format for printf
 mov rsi,rax ; first parameter for printf
 mov rdx,[rax+8] ; second parameter for printf
 mov rax,0 ; no xmm registers
 call printf ; Call C function
 mov rax,[a] ; add 3 to L[0]
 mov rdx,[rax] ; get L[0]
 add rdx,3 ; add
 mov [rax],rdx ; store sum for caller
 mov rdx,[rax+8] ; get L[1]
 add rdx,4 ; add
 mov [rax+8],rdx ; store sum for caller
 pop rsi ; restore registers
 pop rdi ; in reverse order
 Pages - 16
Computer architecture labs
 pop rdx
 mov rsp,rbp ; restore callers stack frame
 pop rbp
 ret ; return
 6.16. Examples 16 – find max and min
; Write a program which reads 5 numbers into an array and
prints the smallest and largest
; number and their location in the array.
; If the user enters 7, 13, -5, 10, 6 then your program should
segment .data
 a: dq 2
 b: dq 0
 ind: dq 0
 cnt: dq 0
 cnt2: dq 0
 mini: dq 0
 maxi: dq 0
 min_pos: dq 0
 max_pos: dq 0
 fmt: dq "%lld ",10,0
 fmt_in: dq "%lld", 0
fmt_out_max: dq "The largest number at index %lld is: %lld ",
10, 0
fmt_out_min: dq "The smallest number at index %lld is: %lld ",
10, 0
segment .bss
 array resq 21
 array2 resq 21
segment .text
global main
extern printf
extern scanf
main:
 push RBP
 mov RAX, 0
 mov RCX, 0
 mov RBX, 0
INPUT_ARRAY:
 cmp RCX, 5
 jz DONE
 mov [cnt], RCX
 mov RAX, 0
 mov RDI, fmt_in
 mov RSI, a
 call scanf
 mov RAX, [a]
 mov RCX, [cnt]
 mov [array+RCX*8], RAX
 Pages - 17
Computer architecture labs
 mov [array2+RCX*8], RAX
 add RBX, [a]
 inc RCX
 jmp INPUT_ARRAY
DONE:
 mov RAX, 0
 mov RCX, 0
 mov RBX, 0
OUTER_LOOP:
 cmp RCX, 5
 jge END_LOOP
 mov [cnt], RCX
 mov RAX, [array+RCX*8]
INNER_LOOP:
 inc RCX
 cmp RCX, 5
 jz OK
 cmp RAX, [array+RCX*8]
 jle INNER_LOOP
 xchg RAX, [array+RCX*8]
 jmp INNER_LOOP
OK:
 mov RCX, [cnt]
 mov [array+RCX*8], RAX
 inc RCX
 jmp OUTER_LOOP
END_LOOP:
 mov RAX, 0
 mov RBX, 0
 mov RCX, 0
 mov RAX, [array+RCX*8]
 mov [mini], RAX
 mov RCX, 4
 mov RAX, [array+RCX*8]
 mov [maxi], RAX
 mov RCX, 0
 mov RAX, 0
 mov RBX, 0
FIND_MAX:
 cmp RCX, 5
 mov [cnt], RCX
 jz PRINT_MAX
 mov RAX, [maxi]
 mov RBX, [array2+RCX*8]
 Pages - 18
Computer architecture labs
 cmp RAX, RBX
 jz PRINT_MAX
 mov RCX, [cnt]
 inc RCX
 jmp FIND_MAX
PRINT_MAX:
 mov RAX, [maxi]
 mov RDI, fmt_out_max
 mov RSI, RCX
 mov RDX, RAX
 call printf
 mov RCX, 0
 mov RAX, 0
 mov RBX, 0
FIND_MIN:
 cmp RCX, 5
 mov [cnt], RCX
 jz PRINT_MIN
 mov RAX, [mini]
 mov RBX, [array2+RCX*8]
 cmp RAX, RBX
 jz PRINT_MIN
 mov RCX, [cnt]
 inc RCX
 jmp FIND_MIN
PRINT_MIN:
 mov RAX, [mini]
 mov RDI, fmt_out_min
 mov RSI, RCX
 mov RDX, RAX
 call printf
END:
 mov RAX, 0
 pop RBP
 ret
 6.17. Example 17
; Write an assembly program that would input twenty numbers
from the user and print
; sum, then the first number, then the 2nd number followed by
3rd number and so on.
segment .data
 a: dq 2
 b: dq 0
 cnt: dq 0
 fmt: dq "%lld ",10,0
 fmt_in: dq "%lld", 0
 Pages - 19
Computer architecture labs
 fmt_out: dq "THE SUM IS: %lld", 10, 0
segment .bss
 array resq 21
segment .text
global main
extern printf
extern scanf
main:
 push RBP
 mov RAX, 0
 mov RCX, 0
 mov RBX, 0
INPUT_ARRAY:
 cmp RCX, 20
 jz DONE
 mov [cnt], RCX
 mov RAX, 0
 mov RDI, fmt_in
 mov RSI, a
 call scanf
 mov RAX, [a]
 mov RCX, [cnt]
 mov [array+RCX*8], RAX
 add RBX, [a]
 inc RCX
 jmp INPUT_ARRAY
DONE:
 mov RAX, 0
 mov RCX, 0
 mov RDI, fmt_out
 mov RSI, RBX
 call printf
 mov RAX, 0
 mov RCX, 0
 mov RBX, 0
PRINT_ARRAY:
 cmp RCX, 20
 jz END
 mov RAX, [array+RCX*8]
 inc RCX
 mov [cnt], RCX
 mov RDI, fmt
 mov RSI, RAX
 call printf
 mov RCX, [cnt]
 jmp PRINT_ARRAY
END:
 Pages - 20
Computer architecture labs
 mov RAX, 0
 pop RBP
ret
 Pages - 21
Computer architecture labs