0% found this document useful (0 votes)
16 views

Lab2023 5 Control Loops

KTMT

Uploaded by

Nhung Hồng
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
16 views

Lab2023 5 Control Loops

KTMT

Uploaded by

Nhung Hồng
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 21

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

You might also like