CodeNet / Языки программирования / Ассемблер / СПРАВОЧНИК по системе программирования ТУРБО АССЕМБЛЕР 2.0
СПРАВОЧНИК по системе программирования ТУРБО АССЕМБЛЕР 2.0
Преобразование размеров данных ----------------------------------------------------------------- Иногда бывает необходимо преобразовать слова в байты или на- оборот. При этом, как и в других действиях, значения могут быть со знаком или без знака. Давайте сначала рассмотрим преобразование слова в байт. Это довольно просто: нужно только избавиться от старшего байта слова. Например: . . . mov ax,5 mov bl,al . . . Здесь значение 5 размером в слово в регистре AX преобразует- ся в байтовое значение 5 в регистре BL. Конечно, вы должны быть уверены, что преобразуемое вами значение поместится в байте. По- пытка преобразовать в байт значение 100h с помощью инструкций: . . . mov dx,100h mov al,dl . . . была бы безуспешной, так как в регистр AL был бы записан только младший (нулевой) байт. Преобразование беззнакового байтового значения в слово зак- лючается просто в обнулении старшего байта слова. Например, инс- трукции: . . . mov cl,12 mov al,cl mov ah,0 . . . преобразуют беззнаковое значение 12 в регистре CL в значение 12 размером в слово в регистре AX. Преобразование в слово байтового значения со знаком несколь- ко более сложно, поэтому в процессоре 8086 для выполнения этой задачи предусмотрена специальная инструкция CBW. Инструкция CBW преобразует байтовое значение со знаком в регистре AL в значение со знаком размером в слово в регистре AX. В следующем фрагменте программы байтовое значение со знаком -1 в регистре DH преобразу- ется в значение со знаком размером в слово в регистре DX (-1): . . . mov dh,-1 mov al,dh cbw mov dx,ax . . . В наборе инструкций процессора 8086 для преобразования слова со знаком в регистре AX в двойное слово со знаком в регистрах DX: AX (старшее слово содержится в регистре AX) предусмотрена специ- альная инструкция CWD. Следующие инструкции преобразуют значение со знаком +10000 (размером в слово), содержащееся в регистре AX, в значение со знаком +10000 (размером в двойное слово), содержа- щееся в паре регистров DX:AX: . . . mov ax,10000 cwd . . . Беззнаковые значения размером в слово можно преобразовать в беззнаковые значения размером в двойное слово путем обнуления старшего слова значения. Доступ к сегментным регистрам ----------------------------------------------------------------- Хотя для перемещения значений в сегментные регистры и из них можно использовать инструкцию MOV, это особый случай, более огра- ниченный, чем другие случаи использования инструкции MOV. Если одним из операндов инструкции MOV является сегментный регистр, то другим операндом должен быть регистр общего назначения или ячейка памяти. Загрузить константу в сегментный регистр непосредственно невозможно, и невозможно непосредственно скопировать один сегмен- тный регистр в другой сегментный регистр. Так как имена сегментов являются константами, необходимо загружать сегментные регистры таким же образом, как общие регист- ры или переменную в памяти. Вот, например, два способа установки регистра ES в значение сегмента .DATA: . . . .DATA DataSeg DW @Data . . . .CODE . . . mov ax,@Data mov es,ax . . . mov ex,[DataSeg] . . . Вместо этого хотелось бы сделать следующее: mov es,@Data ; недопустимо! но это работать не будет. Чтобы скопировать содержимое одного сегментного регистра в другой сегментный регистр, вам придется передать значение через регистр общего назначения или память. Инструкции: . . . mov ax,cs mov ds,ax . . . и . . . push cs pop ds . . . копируют содержимое регистра CS в DS. Первый метод работает быст- рее, но при втором методе требуется меньший объем кода. Не удивляйтесь, при работе с инструкцией MOV вы сталкивае- тесь с ограничениями, когда дело касается сегментных регистров, ведь в большинстве инструкций сегментные регистры вовсе не допус- кается использовать в качестве операндов. Сегментные регистры можно заносить в стек и извлекать из стека, но этим дело и огра- ничивается. В операциях сложения, вычитания, логических операциях или сравнениях их использовать нельзя. Перемещение данных в стек и из стека ----------------------------------------------------------------- Со стеком (областью памяти в сегменте стека, работающей по дисциплине FIFO - "первым-пришел-первым-ушел") вы уже встреча- лись. На вершину стека всегда указывает регистр SP. Для обращения к данным в стеке, с использованием режимов адресации памяти, при которых указателем базы является регистр BP, можно использовать инструкцию MOV. Например, инструкция: mov ax,[bp+4] загружает регистр AX содержимым слова в сегменте стека со смеще- нием BP+4 (доступ к стеку через регистр BP описывается в Главе 2). Однако чаще к стеку обращаются с помощью инструкций PUSH и POP. Инструкция PUSH сохраняет операнд в вершине стека, а инст- рукция POP извлекает значение из вершины стека и сохраняет его в операнде. Например, инструкции: . . . mov ax,1 push ax pop bx . . . заносят значение (равное 1) в регистре AX в вершину стека, затем извлекают 1 из вершины стека и сохраняют ее в BX.