Санның өлшемін өзгерту

Мысал қарастырайық. Айталық ВХ регистріндегі санға AL регистріндегі санды қосу қажет болсын: ВХ=ВХ+AL. Мұнда сөзді байтпен қосу керек, қосылатын сандардың өлшемдері (типтері) сәйкес болу қажеттігі айтылған. Сондықтан, алдымен олардың өлшемдерін сәйкестендіріп алу керек. Ол үшін AL–ді АХ регистрне жазу арқылы сөзге ұзартуға болады.

Егер сан таңбасыз болса, онда жеңіл жасалады. Бұл жағдайда берілген операндтың жоғарғы разрядтарын нөлдермен толтыру арқылы жаңа операнд алынады. Мысалы, егер AL=32=20h, AX=0020h.

MOV AH,0 ;AL ® AX

Таңбалы санлар үшін программаның орындалу барысында бұл мәселені шешу қиынға түседі, опенандтың таңбасын ескеру керек. Осыған орай процессордың командалар жүйесіне типтерді өзгерту командалары енгізілген. Бұл командалар байты сөзге (CBW, AL–ді АХ-ке), сөзді екіеселі сөзге (CWD, АХ-ті DX:AX-ке), сөзді екіеселі сөзге (CWDЕ, АХ-ті ЕAX-ке), екіеселі сөзді (CDQ, EАХ-ті EDX:ЕAX-ке) төртеселі сөзге ұзартады.

CBW және CWD 8086/8088 процессорлары үшін, ал CWDЕ және CDQ 80386 процессоры үшін

Мысалдар:

MOV AL,32 ;AL = 32d = 20h

CBW ;AX = 0020h (+32 саны сөз түрінде)

MOV AL,-32 ;AL =-32 = 0E0h

CBW ;AX = 0FFE0h (-32 саны сөз түрінде)

Жоғарыдағы мысалға оралсақ, сандардың таңбалы немесе таңбасыз болуына байланысты төмендегідей шешіледі:

; таңбасыз сандар үшін

MOV АН,0 ;ALàAX

ADD BX,AX

; таңбалы сандар үшін

CBW

ADD BX,AX

Көбейту командалары

Таңбалы және таңбасыз сандары көбейту амалы әртүрлі алгоритмдермен орындалады. Сол себепті оларды көбейту үшін жеке командалар қарастырылады:

Таңбасыз сандарды көбейту: MUL OP

Таңбалы сандарды көбейту: IMUL OP

Бұл командалардың орындалу алгоритмі әртүрлі болғанымен басқа жағдайдағы әрекеттері бірдей:

Байттарды көбейту: AX= AL * OP (ор: rеg8, mem8)

Сөздерді көбейту: (DX,AX)= AX * OP (op: rеg16, mem16)

Еселі сөздерді көбейту: (EDX,EAX)= AX * OP (op: rеg32, mem32)

Командада көрсетілетін OP - операнд – көбейткіш, ол регистрде немесе жад ұяшығында болуы мүмкін, ал тікелей операнд бола алмайды. Көбейгіштің орны алдын ала белгілі, сондықтан командада айқын көрсетілмейді: ол байттарды көбейткенде AL регистрі, сөздерді көбейткенде AX регистрі, ал екіеселі сөздерді көбейткенде ЕAХ регистріне жазылады.

Нәтиженің орыны да белгілі, сондықтан ол да командада айқын көрсетілмейді. Және көбейтіндіге көбейгіштерден екі есе артық орын беріледі. Байттарды көбейткенде нәтиже сөз өлшемді болады да AX регистріне (АН-қа жоғарғы, ал AL –ге кіші разрядтары), сөздерді көбейткенде нәтиже екіеселі сөз өлшемді болады да DX, AX регистрлеріне (DX-ке жоғарғы, ал AХ–ке кіші разрядтары), ал екіеселі сөздерді көбейткенде нәтиже төртеселі сөз өлшемді болады да ЕDX, ЕAX регистрлеріне (ЕDX-ке жоғарғы, ал ЕAХ–ке кіші разрядтары) жазылады.

Сонымен, көбейтінді екі бөліктен тұрады екен. Нәтиженің бір регистрге сиғандығын программаның орындалу барысында CF және OF регистрлерін тексеру арқылы білуге болады:

· егер нәтиженің жоғарғы бөлігі нөл болса, онда CF=0 және OF=0;

· егер CF=1 және OF=1 болса, онда нәтиже екі бөліктен тұрады.

5.3.4.1-мысал. Айталық Х - мәні таңбалы сан болып келетін байт өлшемді, ал Y- сөз өлшемді айнымалы болсын. Y=X*X*X өрнегін есептеу керек, нәтиже сөз өлшемді болу керек.

Шешуі. ДК-дің арифметикалық командаларын қолданған кезде операндтардың өлшемін, сандардың таңбалы, не табасыз екендігін мұқият қадағалау керек. Ал егер көбейту, бөлу және таңбамен ұзарту операциялары қолданылса, онда осы амалдардың операндтарының қажетті регистрлерде орналасуын қадағалау керек.

Біздің мысалда алдымен Х байтын өз-өзіне көбейтеміз. IMUL командасының операндтарының бірі AL регистрінде орналасу керек болғандықтан ең алдымен Х-ті осы регистрге жазамыз. АХ регистрінде Х*Х өрнегінің нәтижесін аламыз. ДК-де сөзді байтқа көбейтуге болмайтындықтан Х байтын таңбамен сөзге дейін ұзартамыз, ол үшін CBW командасын қолданамыз. Бұл команда АХ регистрін қолданатындықтан АХ регистрін босату керек. X*X*X өрнегінің нәтижесі екіеселі сөз болатындықтан ол DX және АХ регистрлерінде орналасады. Есептің шартына байланысты қорытынды нәтиже сөз өлшемді болу керек, сондықтан DX регистрін ескермесек те болады.

Осының бәрін ескеріп келесі командаларды аламыз:

MOV AL,X

IMUL AL ;AX=X*X (IMUL X қолдануға болады)

MOV BX,AX ;AX регистрін босату

MOV AL,X

CBW ;AX=X сөз ретінде

IMUL BX ;(DX,AX)=X*X*X(DX-ті ескермеуге болады)

MOV Y,AX

5.3.4.2-мысал. Байт өлшемді А, В айнымалылары берілген. y=ab+(а3+1)(в2-1) өрнегін есептеу керек.

Шешуі. Алдымен А және В айнымалыларын көбейтіп, нәтижені сақтап қалу үшін Y–ке меншіктейміз. Сонан соң бірінші жақшадағы амалдарды орындап, нәтижені Z- ке меншіктейміз. Ары қарай екінші жақшаның амалдарын орындап нәтижесін Z-те сақталған бірінші жақшаның мәніне көбейтіп нәтижені Y айнымалысына қосамыз

A DB ? ;A берілетін мәлімет, байт өлшемді

B DB ? ;A берілетін мәлімет, байт өлшемді

Z DW ? ;Z-аралық айнымалы, сөз өлшемді

Y DW ? ;Y-нәтиже, сөз өлшемді

. . .

Программаны тексеру үшін Паскальға кіріктірілген Ассемблерді қолданамыз. Мәліметтерді Паскальда енгізіп-шығарамыз.

Паскальға кіріктірілген Ассемблерде жазылған программа мәтіні:

Program missal5_3_4_2;

Var

a,b:byte; y,z: integer;

begin

Writeln('a='); Readln(m);

Writeln('b='); Readln(n);

ASM

;A мен В-ны көбейтіп Y-ке меншіктейміз

MOV AL,A ;AL=A

MUL B ;AX=AL*B

MOV Y,AX ;Y=AX

;Бірінші жақшаны есептеп нәтижені z-ке меншіктейміз

MOV AL,A ;AL=A

MUL A ;AX=A*A

MUL A ;AX=А*A*A

INC AX ;AX=А*A*A+1

MOV Z,AX ;Z=А*A*A+1

;Екінші жақшаны есептейміз

MOV AL,B ;AL=B

MUL B ;AX=AL*B

DEC AX ;AX=AX-1

;Екінші жақша нәтижесін z-ке көбейтіп y-ке қосамыз

MUL Z ;AX=AX*Z

ADD Y,AX ;Y+AX

End;

Writeln('Нәтиже=',Y);

Readln

end.

Дәріс №4.

Тақырыбы:Арифметикалық командалар.

Жоспары: Бүтін сандарды қосу және алу ерекшеліктері. Қосу және алу командалары. Санның өлшемін өзгерту. Көбейту командалары. Бөлу командалары.

Бөлу командалары

Бөлу командаларыкөбейту тәрізді таңбалы және таңбасыз сандарды бөлу де екі командамен жүзеге асырылады:

Таңбасыз бүтін санды бөлу: DIV op

Таңбалы бүтін санды бөлу: IDIV op

Бөлгіш жад ұяшығында немесе регистрде болуы мүмкін, және де өлшемі 8 (байт), 16 (сөз) және 32 (екіеселі сөз) бит бола алады. Бөлінгіштің орны алдын ала белгілі, сондықтан командада айқын көрсетілмейді: сөзді байтқа бөлгенде AХ регистрі, екіеселі сөзді сөзге бөлгенде (DX,AX) регистрлері, ал төртеселі сөзді екіеселі сөзге бөлгенде (EDX,EAX) регистрлерінде деп есептеледі. Бөлу командасының нәтижесінде бөліндінің бүтіні мен қалдығы табылады.

Сөзді байтқа бөлу:

AH:=AX mod op, AL:=AX div op (op:reg8,mem8)

Екіеселі сөзді сөзге бөлу:

DX:=(DX,AX) mod op, AX:=(DX,AX)div op (op:reg16,mem16)

Төртеселі сөзді сөзге бөлу:

EDX:=(EDX,EAX) mod op, AX:=(EDX,EAX)div op (op:reg32,mem32)

Бөлу командалары орындалғаннан соң күй жалаушалары өзгетілмейді, бірақ «нөлге бөлу» қателігі туындауы мүмкін. Бұл қателіктің пайда болу себептері:

· бөлгіш нөлге тең;

· бөлінді оған берілген разрядтар торына симайды.

Бір типті сандарды бөлуде бөлінгішті ұзарту үшін көбіне cандардың өлшемін өзгерту командалары қолданылады. Мысалы AL:=AL div CH былай жасалады:

; таңбасыз сандар үшін

MOV АН,0 ;ALàAX

DIV CH ;AL = AL div CH (AH = AL mod CH)

; таңбалы сандар үшін

CBW ;ALàAX

ADD BX,AX ;AL = AL div CH (AH = AL mod CH)

 

5.3.5.1-мысал. Келесі өрнекті есептеу керек:

Мұндағы N, M байт өлшемді айнымалылар.

Шешуі. Өрнекті үш бөлікке бөліп есептейміз. Ең алдымен берілген бөлшектің бөлімін есептеп аламыз. Нәтижені сақтап қалып АХ регистрін босату үшін қандай да бір айнымалаға (A-ға) меншіктеп қоямыз. Ол айнымалы сөз өлшемді болуы тиісті. Екіншіден, бөлшектің алымын есептеп, шыққан нәтижені А-ға бөлеміз. Ассемблер А айнымалысын байт ретінде қабылдау үшін PTR командасын қолданамыз. Ең соңында бөлудің нәтижесі қалдық және бүтін бөлік түрінде AL және AH регистрлернде сақталатындықтан сәкесінше осы регистрлердегі нәтижелерді Z және Y айнымалыларына меншіктейміз.

N DB ? ;n берілетін мәлімет, байт өлшемді

M DB ? ;m берілетін мәлімет, байт өлшемді

Y DB ? ;Y-ке нәтиженің бүтіні жазылады, байт өлшемді

Z DB ? ;Z-ке нәтиженің бүтіні жазылады, байт өлшемді

A DW ? ;A-аралық айнымалы, сөз өлшемді

. . .

Мәліметтерді енгізу-шығаруды Паскальда жасаймыз. Паскальдағы программа негізгі программа болады да, одан ассемблер модулі шақырылады.

Паскальда жазылған MIS5_3_5_1PAS.pas программаның мәтіні:

Program missal5_3_5_1;

{$L mis5_3_5_1.obj} { mis5_3_5_1.obj Ассемблер модулін қосу}

{$f+}{FAR–процедуралар мен функцияларды шақыру директивасы}

Var

m,n,y,z:byte;

{Ассемблерде жазылған сыртқы процедураның сипаттамасы}

Procedure mis5_3_5_1 (var m,n:byte; var y,z:byte);{FAR;} external;

begin

Writeln('m='); Readln(m);

Writeln('n='); Readln(n);

mis5_3_5_1(m,n,y,z);

Writeln('Бүтіні=',Y,';Қалдығы=',z);

Readln

end.

Ассемблерде жазылған MIS5_3_5_1ASM.asm модулінің мәтіні:

; mis5_3_5_1.asm

.MODEL Large

.data

; мәліметтер Паскальдан алынып-беріледі

; m,n берілетін мәлімет, байт өлшемді

Extrn m:byte, n:byte

; Y-ке нәтиженің бүтіні жазылады, байт өлшемді

; Z-ке нәтиженің бүтіні жазылады, байт өлшемді

Extrn Y:byte, Z:byte

A DW ? ;A-жергілікті айнымалы, сөз өлшемді

.code

Public mis5_3_5_1

mis5_3_5_1 proc far

;Бөлшектің бөлімін есептеу

MOV AL,N ;AL=N

MUL N

MUL N ;AX=AL*N*N

INC AX ;AX=AX+1

MOV A,AX ;A=AX

;Бөлшектің алымын есептеу

MOV AL,M ;AL=M

MUL M ;AX=AL*M

DEC AX ;AX=AX-1

DIV BYTE PTR A ;A-ны байт ретінде қабылдау

;Бөлінді нәтижесін Y және Z айнымалыларына меншіктеу

MOV Y,AL ;Y=AX DIV A

MOV Z,AH ;Z=AX MOD A

ret

mis5_3_5_1 endp End

 

Дәріс №5

Тақырыбы: Шартсыз өту. Салыстыру және шартты өту командалары. Шартты өту командалары

Жоспары. Шартсыз өту. Тура өту. Жанама өту. Сегментіші (жақын) өту. Сегментарлық (алшақ) өту.Салыстыру командаларынан соң қолданылатын шартты өту командалары. Қандайда бір анықталған жалаушалардың мәндеріне байланысты өту. СХ регистрінің мәнін тексеру арқылы өту.

 

Әдетте машиналық программаның командалары, жадта жазылған күйінде, бірінен соң бірі біртіндеп орындалады. Бірақта программаның орындалу алгоритмі бойынша ол қалыпты ретті өзгертіп отыру қажет болады. Ол үшін, яғни келесі орындалатын командаға өту үшін басқару командалары (шешім қабылдау командалары) қолданылады. Бұл командаларды программалау тілдерінде қысқаша өту командаларды деп те атайды. Біз осы терминді пайдаланамыз.

Өту командалары шартты өту және шартсыз өту болып бөлінеді. Егер өту тек қана қандайда бір шарттың орындалуына байланысты жасалса, ондай өту шартты өту, ал ешқандай шартқа байланыссыз жасалса шартсыз өту деп аталады.

Шешім қабылдау командаларымен танысуды шарттыз өту командаларынан бастаймыз.