Operations are
performed repeatedly via loops. In
higher level languages, loops are hand-manufactured
via conditions and branches (If Statement and Gotos) or using language defined
structured loop statements. The latter include Repeat, While, and For
Statements.
Our first
assembler example implements a hand-manufactured
loop, the one you should avoid. The loop body is repeated until a particular
value (sentinel) is found. However, the loop body is entered unconditionally;
hence this resembles a Repeat Statement.
The second
assembler example knows the iteration count at the time of assembly, hence the
x86 provided loop instruction can be used. This loop body can be characterized
as a For Statement which is known to be executed at least once.
The third
example does not know the number of iterations at the time of assembly. Hence,
before entering the loop body for the first time, a check must be made for the
loop count to be less than or equal to zero. If so, the body is bypassed; else
the body is entered and executed countably many times. Thus, the loop resembles
a C-style For Statement.
·
Motivation
·
Definitions
·
Repeat Loop
with Sentinel
·
For Loop
with A-Priori Loop Count
·
For Loop
with Iteration Count Unknown at Assembly Time
·
Exercises
·
Repeated
execution necessary, since number of steps varies with data values
·
Special
operations provided by hardware speed-up loop overhead
·
On x86
architecture with few registers, cx takes over special loop-count role
·
On x86,
loop instructions does the following (in Pseudo Code):
·
loop next
is executed: (if (--cx) > 0 ) goto next;
·
New x86
instruction to test for dangerous, initial zero value, is: jcxz
on x86 architecture
Transfer
of control to a destination that is generally not the instruction following the
branch. Synonym: Jump. The destination is an explicit or implicit operand of
the branch instruction.
Loop,
in which the number of iterations can be computed (is known) before the loop
body starts.
High-level
construct implementing a countable loop.
Most
general type of loop. The number of iterations cannot be computed before, not
even during the execution of the loop. Generally, the number of iterations
depends on data that are input via read operations. Also, the number of steps
may depend on the precision of a computer (floating-point) result and thus is
not known until the end.
Synonym
for Branch. Transfer of control to a
destination that is generally not the instruction following the jump. The
destination is an explicit or implicit operand of the jump.
Program
portion executed repeatedly. This is the actual work to be accomplished. The
rest is loop overhead. Goal to minimize that overhead.
Loop
in which the body is entered unconditionally. The number of iterations is
generally not known until the loop terminates.
Predefined
value, against which an operand is compared during each operation. When the sentinel is found, a special operation
takes place. Usually, a loop body terminates.
Loop
in which the body is entered after first checking whether the condition for execution
is true. If not, the body is not executed. This is also used as the termination
criterion. The number of iterations is generally not known until the loop
terminates.
·
We define
character string in data segment, all 0..f hex digits
·
Data area
is named chars and being used as address (data offset)
·
Sentinel
for loop termination is #
·
Register bx
used as index register
·
Note that
only bx, si, di, and
bp ccan be used for indexing
·
Learn cmp
instruction, which compares by subtracting, and then sets flags
·
Learn to
know conditional (jcc) and unconditional jump (jmp)
·
See use of
labels as destinations of jumps
·
Output of
program is: 0123456789abcdef
; Source file: loop1.asm
; Date: 2-2-1997
; Purpose: use, syntax of indexing char array w.
sentinel
start macro ;
no parameters
mov ax, @data ; @data predefined macro
mov ds, ax ; now data segment reg set
endm ;
end macro: start
termin macro ret_code ; 1 parameter: return code
mov ah, 4ch ; terminate: set ah + al
mov al, ret_code ; any errors? If /= 0
int 21h ; call DOS for help
endm ;
end macro: termin
Char_Out =
2h
Sentin = '#'
.model small
.data
chars db "0123456789abcdef",
Sentin
.code
main: start
mov ah, Char_Out ; set up ah for DOS call
mov bx, 0 ; to index string, init 0
next: mov dl,
chars[bx] ; find next char
inc bx ; increment index register
cmp dl, Sentin ; found sentinel?
je done ; yep, so stop
int 21h ; nop, so print it
jmp next ; try next one; could be sentinel
done: termin 0 ; no errors if we reach
end main ; start here!
·
Again we
define character string in data segment, all 0..f hex digits
·
Have no
sentinel
·
Assume that
loop is executed exactly 16 times, known a-priori
·
Again use
register bx as index register
·
Learn loop
instruction, which tracks loop count and conditional branch
·
Loop
instruction on x86 subtracts 1 from cx
·
If cx = 0,
fall through; else branch to target, which is part of instruction
·
Output of
program is: 0123456789abcdef
; Source file: loop2.asm
; Purpose: use, syntax of indexing char array
; loop is "countable" we know # of elements
; b 4 start of loop; we know at assembly time
. . . same macros start, termin
Char_Out =
2h
Num_El = 10h ; 16 elements in chars array[]
.model small
.data
chars db "0123456789abcdef"
.code
main: start
mov ah, Char_Out ; set up ah for DOS call
mov bx, 0 ; initial index off 'chars'
mov cx, Num_El ; we know # iterations a priori
next: mov dl,
chars[bx] ; find next char
inc bx ; increment index register
int 21h ; print it
loop next ; try next one; could be 0: end
·
Again we
define character string in data segment, all 0..f hex
digits, no sentinel
·
Assume
iteration count is not known a-priori
·
Again use
register bx as index register
·
Must check
whether cx is less than or equal to zero
·
If so: bad
news: Looping will be excessive
·
Loop
instruction on x86 subtracts 1 from cx; should start with positive value
·
New
instruction jcxz: if cx is already zero at start, branch and dont enter loop
body
·
Output of
program is: 0123456789abcdef
; Source file: loop3.asm
; Purpose: use, syntax of indexing char array
; loop is "countable"; this time we know # of
; elements b 4 start of loop; but NOT at assembly time
.model small
.data
chars db "0123456789abcdef"
.code
main: start
mov ah, Char_Out ; set up ah for DOS call
mov bx, 0 ; initial index off 'chars'
; let's assume that # elements is read at run-time
; here we just fake this reading by brute-force setting
; but the point is: The # could be non-positive!
mov cx, 16 ; pretend we read value of cx
cmp cx, 0 ; then test if cx < 0
jl done_neg ; if it is, jump
jcxz done_zero ; if it is zero, jump also
; if we reach this: ;
cx is positive
next: mov dl,
[chars][bx] ; find next char
inc bx ;
increment index register
int 21h ; output next character
loop next ; try next one; could be end
done: termin 0 ; no errors if we reach
done_neg: termin 1 ; another error code. Not 0
done_zero: termin 2 ; an yet another error
end main ; start here!
t.b.d.