Введение
При более глубоком изучении программирования необходимо освоить механизм
реализации операторов языка программирования и связь его с низкоуровневым
программированием (использование языка ассемблера).
Рассмотрим механизм реализации выражений. Например, нам необходимо вычислить
выражение: x=sin(20+a)*(y-v):
Один из многочисленных вариантов может выглядеть так:
| mov r1,a |
;загрузить в регистр R1 значение ячейки a |
| mov r2,20 |
;загрузить в регистр R2 значение константы 20 |
| add r1,r2 |
;сложить R1 и R2, результат поместить в R1 |
| push r1 |
;занести в стек значение R1, это будет параметр для функции sin |
| call sin |
;вызвать функцию sin |
| pull r1 |
;забрать из стека результат вычисления синуса |
| mov r2,y |
;загрузить в регистр R2 значение ячейки y |
| mov r3,v |
;загрузить в регистр R3 значение ячейки v |
| sub r3,r2 |
;произвести вычитание, результат поместить в R3 |
| mult r1,r3 |
;выполнить умножение, результат поместить в R1 |
| mov x,r1 |
;запомнить содержимое R1 в ячейку x |
| Stop |
;останов |
Реализация условных операторов. Рассмотрим пример:
- if( k==10 ) x=20; else z=z+30;
Первоначально вычисляется условное выражение и если результат не равен нулю, то
выполняется оператор x=20; В противном случае оператор x=x+20; Тогда программа
на ассемблере приблизительно выглядит так:
|
Mov r1,k |
;загрузить в регистр R1 значение ячейки k |
|
Mov r2,10 |
;загрузить в регистр R2 значение 10 |
|
Cmp r1,r2 |
;сравнить содержимое регистров, если равны, то установить флаг Z в единицу |
|
jne met1 |
;переход на метку, если Z равен нулю |
|
Mov r1,20 |
; загрузить в регистр R1 значение 20 |
|
Mov x,r1 |
;запомнить содержимое R1 в ячейку x |
|
bra next |
;безусловный переход на продолжение |
| met1 |
mov r1,z |
; загрузить в регистр R1 значение ячейки z |
|
mov r2,30 |
; загрузить в регистр R2 значение 30 |
|
add r1,r2 |
;произвести сложение, результат запомнить в R1 |
|
mov z,r1 |
;содержимое R1 запомнить в ячейку z |
| Next |
.... |
; |
Механизм реализации цикла while. Рассмотрим этот механизм на примере:
-
s=0;
while(i<10) i++; s=s+i;
|
clr r3 |
; очистить r3 , это будет сумма (s) |
|
clr r1 |
;очистить r1, это будет счетчик (i) |
|
mov r2,10 |
; загрузить в регистр R2 значение 10 |
| Begin |
cmp r1,r2 |
;сравнить r1 и r2 |
|
bge next |
;если значение r1 больше или равно, то перейти на метку next |
|
inc r1 |
;увеличить значение r1 на единицу |
|
add r3,r1 |
;выполнить сложение s=s+i |
|
bra begin |
;перейти по метке begin (в начало цикла) |
| Next |
mov i,r1 |
;выход из цикла, запомнить значение счетчика |
|
mov s,r3 |
;запомнить значение суммы |
Рассмотрим механизм реализации оператора switch на следующем примере: -
switch(ch)
{
case ’a’: x=1; break;
case ’b’: y=2; break;
case ’c’: z=3; break;
default: m=10;
}
Тогда ассемблерный код будет следующий:
|
mov r1.ch |
;загрузить в r1 значение ch |
|
cmp r1,’a’ |
;сравнить с кодом символа ’a’ |
|
bne met1 |
;если это не символ ’a’, то смотреть следующий символ |
|
mov r2,1 |
;иначе x присвоить 1 |
|
mov x,r2 |
; |
|
bra next |
;выход на конец оператора switch |
| met1 |
cmp r1,’b’ |
;сравнить с кодом символа ’b’ |
|
bne met2 |
;если это не символ ’b’, то смотреть следующий символ |
|
mov r2,3 |
;иначе y присвоить 2 |
|
mov y,r2 |
; |
|
bra next |
; выход на конец оператора switch |
| met2 |
cmp r1,’c’ |
;сравнить с кодом символа ’c’ |
|
bne met3 |
;если это не символ ’c’, то смотреть следующий символ |
|
mov r2,3 |
;иначе z присвоить 3 |
|
mov z,r2
|
; |
|
bra next |
; выход на конец оператора switch |
| met3 |
mov r2,10 |
;во всех остальных случаях |
|
mov m,r2 |
;ячейке m присвоить значение 10. |
| Next |
.... |
;продолжение |
|