 |
.MODEL SMALL
.STACK 200h
.DATA
Delay:
mov cx,0
DelayLoop:
loop DelayLoop
ret
ProgramStart:
call Delay ; пауза на время,
; необходимое для
; выполнения 64 циклов
mov ah,4ch
int 21h
END ProgramStart
Выполнение здесь начинается не на первой инструкции исходно-
го кода (MOV CX,0) по метке Delay. Вместо этого выполнение начи-
нается с инструкции CALL Delay по метке ProgramStart, как опреде-
лено в директиве END.
Если программа состоит только из одного модуля (то есть од-
ного исходного файла), то в директиве END всегда нужно определять
адрес запуска программы. В программе, состоящей из нескольких мо-
дулей, определять адрес запуска программы следует только в дирек-
тиве END модуля, содержащего инструкцию, с которой должно начать-
ся выполнение программы. В директивах END других модулей должно
указываться только ключевое слово END и нечего более. В самом
деле: каждая программа должна иметь точку начала выполнения, но
было бы бессмысленно иметь несколько таких точек. Убедитесь в
том, что вашей программе имеется один (и только один) адрес нача-
ла выполнения. (Кстати, если в вашей программе имеется два таких
адреса, компоновщик TLINK использует только первый адрес, который
он обнаруживает, и игнорирует другой.)
Операнды
-----------------------------------------------------------------
Мнемоники инструкций и директивы сообщают Турбо Ассемблеру,
что нужно делать. С другой стороны, операнды указывают Турбо Ас-
семблеру, какие регистры, параметры, ячейки памяти и т.д. нужно
связать с каждым вхождением инструкции или директивы. Инструкция
MOV (перемещение данных) сама по себе ничего не означает. Чтобы
указать Турбо Ассемблеру, откуда нужно извлечь перемещаемое зна-
чение и где его сохранить, необходимы операнды.
Для различных инструкций требуются 0, 1, 2 или более операн-
дов. В действительности различными директивами может восприни-
маться любое число операндов, которое может уместиться на одной
строке. Правильное число операндов зависит от конкретной инструк-
ции или директивы. (В общем случае допускается три операнда.)
Возможные операнды включают в себя регистры, константы, метки,
переменные в памяти и текстовые строки.
Какие функции выполняет инструкция с одним операндом, доста-
точно очевидно: она выполняет операции с этим операндом. Напри-
мер:
push ax
заносит регистр AX в стек. Инструкции без операндов еще более
очевидны. Однако, что происходит в случае инструкции с двумя опе-
рандами, один из которых является источником, а остальные прием-
ником? Например, когда процессор 8086 выполняет инструкцию:
mov ax,bx
то из какого регистра он считывает значение, и в какой регистр
записывает?
Вы можете посчитать, что словесным эквивалентом данной
инструкции будет "переместить содержимое AX в BX", но это не так.
Вместо этого инструкция MOV помещает содержимое BX в AX. Можно
использовать следующее правило: замените в инструкции MOV запятую
между операндами знаком равенства, после чего она приобретет вид
оператора присваивания, аналогичный языку Си (или Паскаль). При
таком подходе инструкция MOV преобразуется в вид:
ax = bx;
Это позволит вам легче запомнить работу данной инструкции.
На самом деле в использовании правого операнда в качестве
источника есть некоторая доля путаницы, но по крайней мере в Ас-
семблере процессора 8086 это так, и скоро вы это используете.
Регистровые операнды
-----------------------------------------------------------------
Вероятно регистровые операнды являются наиболее часто ис-
пользуемыми в инструкциях операндами. Регистры могут использо-
ваться в качестве источника (исходный операнд) или приемника (це-
левой операнд) и при некоторых обстоятельствах могут даже содер-
жать адрес, на который нужно выполнить переход. С регистрами мож-
но делать много того, чего нельзя делать с константами, метками
или переменными в памяти. С другой стороны, имеются некоторые
инструкции, в которых можно использовать только регистровые опе-
ранды.
Приведем некоторые примеры регистровых операндов:
mov al,ax
push dl
xchg al,dl
ror dx,cl
in al,dx
inc sl
Регистровые операнды могут использоваться вместе с другими
операндами:
mov al,1
add [BaseCount],cx
cmp si,[bx]
Использование регистровых операндов не требует обширных по-
яснений. Чтобы использовать регистр в качестве операнда, вы зада-
ете имя этого регистра и использующую регистр инструкцию. Если
имеется два операнда и регистровым операндом является самый пра-
вый операнд, то он будет исходным регистром (источником), а если
самым левым операндом - то это целевой регистр (приемник). Если в
инструкции требуется два источника, то может присутствовать еще
один исходный регистр. Например, во фрагменте программы:
.
.
.
mov cx,1
mov dx,2
sub dx,cx
.
.
.
регистр CX устанавливается в значение 1, DX - в значение 2, а за-
тем из регистра DX вычитается CX и результат (1) снова записыва-
ется в регистр DX. В инструкции SUB CX является правым операндом,
поэтому это исходный регистр (источник). DX - самый левый опе-
ранд, поэтому он одновременно является вторым источником и прием-
ником. Кстати, действие данной инструкции SUB (вычитание) выража-
ется словами, как "вычесть CX из DX". Использование метода
преобразования в код языка Си для облегчения запоминания инструк-
ций позволяет преобразовать данную инструкцию SUB к виду:
dx -= cx;
а на Паскале это будет выглядеть, как:
dx := dx - cx;
Операнды-константы
-----------------------------------------------------------------
Регистры прекрасно подходят для хранения значений перемен-
ных, но часто в операндах требуется использовать постоянное зна-
чение. Например, предположим, вы хотите в цикле уменьшать значе-
ние регистра SI на 4, повторяя цикл, пока значение SI не станет
равным 0. Можно использовать следующие операции:
.
.
.
CountByFourLoop:
.
.
.
dec si
dec si
dec si
dec si
jnz CountByFourLoop
.
.
.
Однако намного проще использовать инструкции:
.
.
.
CountByFourLoop:
.
.
.
sub si,1
jnz CountByFourLoop
.
.
.
В качестве постоянных операндов (операндов-констант) можно
использовать также символы, поскольку символ представляет собой
определенное значение. Например, так как символ A имеет десятич-
ное значение 65, то следующие две инструкции эквивалентны:
.
.
.
|