Дейін» циклын ұйымдастыру.
Мысалға Паскальдың
repeat <циклдың денесі> until X<=0; операторын алайық.
Бұл оператордың Ассемблерде жүзеге асырылу сүлбесі:
BEGIN: | циклдың денесіне сәйкес командалар тобы | |
CMP X, 0 | ;Xпен 0 салыстырады | |
JG BEGIN | ;X >0 à BEGIN |
Бұл сұлба бойынша алдымен циклдың денесіне сәйкес командалар тобы орындалып (ең болмағанда бір рет), соңында келесі циклға өту шарты тексеріледі (Паскальда циклдан шығу шарты тексерілетін): егер шарт «ақиқат» болса, онда циклдың денесі қайталанады, ал егер «жалған» болса, онда цикл аяқталады.
6.3.5-мысал. Рнатурал саны берілген. Осы сан алғашқы натурал сандардың көбейтіндісі болса неше көбейткіш алынғанын анықтап N-ге, ал болмаса Х-ке 1-ді меншіктеу керек. Р сөз өлшемді, ал N мен Х байт өлшемді болсын.
Шешуі. Қандайда бір көмекші айнымалы (айталық p1) аламыз. Бірден бастап натурал сандарды біртіндеп көбейтіп осы айнымалыға жазамыз. Табылған көбейтінді p1 берілген Р санынан аспағанша (p1< p) циклды қайталаймыз. Цикл аяқталғанда циклдың қайталану саны n неше көбейткіш алынғанын көрсетеді. Егер Р≠p1 болса, X- ке 1-ді меншіктейміз (X=1).
P DW 0 ;Р берілген натурал сан, сөз өлшемді
N DB 0 ;N анықталатын көбейткіштер саны, байт өлшемді
X DB 0 ;Х көмекші айнымалы, байт өлшемді
. . .
Mov n,1 ;n=1
mov p1,1 ;p1=1 көмекші айнымалы, сөз өлшемді
;Циклдың денесі
l1: mov ax,p1 ;p1à ax
mul n ;p1* N
mov p1,ax ;p1= p1* N
inc n ;n= n +1
;Циклдың аяқталуын тексеру
cmp ax,p ;p1< p ?
jl l1 ;p1< p болса à l1
;p саны алғашқы n натурал сандардың
;көбейтіндісі болатынын тексеру
cmp ax,p ;p1=p ?
jle l2 ;p1=p болса à l2
mov x,1 ;x=1
l2:
. . .
6.3.6 -мысал. n натурал саны берілген. Осы санның цифрларының қосындысын табу керек (мысалы, n = 7528 болса нәтиже: 7+5+2+8=22).
Шешуі. Берілген санның цифрларын табу үшін сол санды 10-ға (сан ондық санау жүйесінде болғандықтан) бөлеміз, табылған бөліндіні тағыда 10-ға бөлеміз осы процесті бөлінді нөлге жеткенше қайталаймыз. Әр бөлудің қалдығы санның цифрларын береді, оларды қосып отырамыз.
N DD 0 ;N берілген натурал сан, екіеселі сөз өлшемді
S DB 0 ;S-қа саның цифрларының қосындысы жазылады
. . .
mov x,10 ;X=10
mov s,0 ;s=0
l1: mov ax,n ;ax=N
div x ;N div 10
add s,ah ;s=s+N mod 10
mov ah,0 ;AL-ді АХ-ке ұзарту үшін
mov n,ax ;N=N div 10
cmp n,0 ;N≠0 ?
jne l1 ;N≠0 à l1
. . .
Іс жүзінде циклдың саны белгілі болатын жағдай жиі кездеседі, ондай жағдай Паскальда for операторымен жүзеге асырылады, ал Ассемблерде арнайы циклды басқару командалары қосылған.
Дәріс №8
Тақырыбы:Циклдарды басқару командалары.
Жоспары.LOOP, LOOPPE/ LOOPPZ және LOOPNE/LOOPNZ командалары. Мысалдар.
Циклдарды басқару командалары
LOOP командасы
LOOP командасы жоғары дәрежелі тілдердегі For операторы тәрізді цикл есептеуішін автоматты түрде азайту арқылы ұйымдастырылады.
Айталық, қандай да бір командалар тобын (циклдың денесін ) N рет қайталау керек болсын, онда ассемблерде мұндай циклды келесі сұлба бойынша ұйымдастыруға болады:
MOV CX,N / MOV ECX,N | ;CX = N / ECX = N | |
BEGIN: | циклдың денесіне сәйкес командалар тобы | |
DEC CX / DEC ECX | ;CX = CX-1 / ECX=ECX-1 | |
CMP CX,0 / CMP ECX | ;CX = 0? / ECX=0?,0 | |
JNE | ;CX ≠ 0 / ECX≠0→ BEGIN |
Соңғы үш команда әр циклдардың соңында пайдаланылады. Сол себепті процессордың командалар жүйесіне, осы үш команданың жұмыстарын атқаратын, арнайы макрокоманда енгізілген:
LOOP <белгі>
LOOP командасының көмегімен жоғарыдағы сүлбе былайша жазылады:
MOV CX,N / MOV ECX,N | ;CX:=N / ECX:=N | |
BEGIN: | циклдың денесіне сәйкес командалар тобы | |
LOOP BEGIN | ;CX / ECX>0 à BEGIN |
Ықшамды болды, сонымен қатар LOOP командасы үш командаға қарағанда жылдамырақ орындалады.
6.4.1.1 -мысал.N натурал саны берілген
S=1! + 2! + … + N! өрнегін есептеу керек.
Шешуі. Қосылғыштар саны N болғандықтан, LOOP командасын пайдалану үшін N-ді СХ регистріне жазамыз. Әр циклда біртіндеп k факториалды есептеп оны қандайда бір айнымалыға (s=s+k!)қосып отырамыз.
N DW ? ; N қосылғыштар саны
S DD ? ;S қосынды меншіктелетін айнымалы
...
mov s,0 ;s=0, қосындының алғашқы мәні
mov f,1 ;f=1, факторалдың алғашқы мәні
mov k,1 ; k=1
mov cХ,n ; cХ=n
l: mov eax,f ; eax=f
mul k ; f*k
mov f,eax ; f=f*k
add s,eax ;
inc k ; k= k+1
loop l ; à L
. . .
6.4.1.2 -мысал. Фибоначчи саны (fn) f1=f2=1, fn=fn-1+fn-2, мұнда n=3,4,… формулаларымен анықталады. Fn-ті анықтау керек.
Шешуі. Фибоначчидің n-ші санын табу үшін циклды n-2 рет орындау керек, себебі, алғашқы екі мәні белгілі, сондықтан СХ регистріне (N-2) -ні жазамыз. Әр циклда алдыңғы екі сан қосылып кезекті сан анықталады.
f1 DW 1 ;f1-Фибоначчидің 1-ші саны
f2 DW 1 ;f2 -Фибоначчидің 2-ші саны
fn DW ? ;fn -Фибоначчидің n-ші саны
. . .
MOV F1,1 ;F1=1
MOV F2,1 ;CX=N
SUB CX,2 ;CX=N-2
L: MOV AX,F1 ;AX=F1
ADD AX,F2 ;AX= F1+F2
MOV FN,AX ;FN= F1+F2
MOV BX,F2 ;BX=F2
MOV F1,BX ;F1=BX
MOV F2,AX ;F2=AX
LOOP L ;àL
. . .
6.4.1.3 -мысал. N натурал саны берілген
өрнегін есептеу керек.
Шешуі. Бұл мысалда N қосылғыш қосу керек. Әр қосылғыш kk (мұнда k=1,2,... ,n) өрнегімен есептеледі, яғни циклдың ішінде цикл ұйымдастыру қажет. Ішкі циклда да LOOP командасы қолданылатын болса, СХ регистрінің мәнін сақтап қалып, сыртқы циклға өтер алдында кайтадан қалпына келіру керек.
N DB ? ;N қосылғыштар саны
K DB ? ;K көмекші айнымалы
S DD ? ;S қосынды меншіктелетін айнымалы
D DD ? ;D kk меншіктелетін айнымалы
. . .
MOV S,0 ; S=0 қосындының алғашқы мәні
MOV CX,N ; CX=N сыртқы цикл есептегіші
MOV K,1 ; K=1
;сыртқы циклдың басталуы
L1: MOV D,1 ; D=1 қосылғыштың алғашқы мәні
MOV X,CX ; X=CX CX-ті сақтап қалу
MOV CX,K ; CX=K ішкі цикл есептегіші
;ішкі циклдың басталуы
L2: MOV EAX,D ; EAX=D
MUL K ; D*K
MOV D,EAX ; D=D*K
LOOP L2 ; à L1
INC K ; K=K+1
ADD S,EAX ; S=s+kk
MOV CX,X ; CX=X, CX-ті қалпына келтіру
LOOP L1 ; à L2