Lab2023 5 Control Loops
Lab2023 5 Control Loops
2. Prerequest
- review the theory of assembly language
3. Tools
- Computer with installed softwares
4. Duration
- 4 hours
5. Contents:
5.1. Introduction
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.
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.
For example,
loopStart:
last:
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.
Instruction Explanation
jmp startLoop
jmp last
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
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*
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.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