Операційна система Windows. Системне програмування в MASM.

ФЛАГОВИЙ РЕГІСТР

Цей pегістр містить 16 біт прапорів, що керуються різними командами для індикації стану операції. В усіх випадках прапори зберігають своє значення доти, поки інша команда не змінить його. Флаговий регістр містить наступні дев'ять використовуваних біт (зірочками відзначені невикористовувані біти):

Номер біта: 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0

Прапор: * * * * O D I T S Z * A * P * C

Розглянемо ці прапори в послідовності праворуч ліворуч.

CF (Carry Flag) - прапор переносу. Містить значення "переносів" (0 чи 1) зі старшого розряду при арифметичес ких операціях і деяких операціях зрушення і циклічного зрушення.

PF (Parity Flag) - прапор парності. Перевіряє молодші вісім біт результат- тов операцій над даними. Непарне число біт приводить до установки цього прапора в 0, а парне - у 1. Не варто плутати прапор парності з бітом контро- лю на парність.

AF (Auxiliary Carry Flag) - додатковий прапор переносу. Встановлюється в 1, якщо арифметична операція приводить до переносу четвертого праворуч біта (біт номер 3) у регистро виття однобайтовой команді. Даний прапор має відношення до арифметичних операцій над символами коду ASCII і до десяткових упакованим полям.

ZF (Zero Flag) - прапор нуля. Встановлюється в якості результату aрифметичних команд і команд порівняння. Як це не дивно, ненульовий результат приводить до установки нульового значення цього прапора, а нульовий - до установки одиничного значення. Існуюча невідповідність є, однак, логічно правильною, тому що 0 позначає "ні" (т.е. результат не дорівнює нулю), а одиниця позначає "так" (т.е. результат дорівнює нулю). Команди умовного переходу JE і JZ перевіряють цей прапор. SF (SIgn Flag) - знаковий прапор. Встановлюється у відповідності зі знаком результату (старшого біта) після арифметичних опеpацій: позитивний результат установлює 0, а негативний - 1. Команди умовного переходу JG і JL перевіряють цей прапор.

TF (Trap Flag) - прапор покрокового виконання. Цей прапор вам уже прихо- дилося встановлювати, коли використовувалася доманда Т в отладчике DEBUG. Якщо цей прапор встановлений в единичное cостояние, те процесор переходить у режим покрокового виконання команд, тобто в кожен момент виконується одна команда під користувальницьким керуванням.

IF (Interrupt Flag) - прапор переривання. При нульовому складаючись нии цього прапора переривання заборонені, при одиничному - дозволені.

DF (DIrection Flag) - прапор напрямку. Використовується в строкових опера- ціях для визначення напрямку передачі даних. При нульовому стані команда збільшує вмістрегістрів SI і DI, викликаючи передачу даних ліворуч праворуч, при нульовому - зменшує вміст цих регістрів, викликаючи передачу даних праворуч ліворуч (див. гл.11).

OF (Overflow Flag) - прапор переповнення. Фіксує арифметическое переповнення, тобто перенос в/из старшого (знакового) біта при знакових арифметичних операціях. Як приклад: команда CMP порівнює два операнда і воздействуте на прапори AF, CF, OF, PF, SF, ZF. Однак, немає необхідності перевіряти всі ці прапори по окремості. У сле- прикладі, що дує, перевіряється чи містить регістр BX нульове значення:

CMP BX,00 ;Порівняння BX з нулем

JZ B50; Перехід на B50 якщо нуль. (дії при ненулі)

B50: ... ;Крапка переходу при BX=0

Якщо BX містить нульове значення, команда CMP установлює прапор нуля ZF в одиничний стан, і можливо змінює (чи немає) інші прапори. Команда JZ (перехлд якщо нуль) перевіряє тільки прапор ZF. При одиничному значенні ZF, що позначаєнульова ознака, команда передає керування на адресу, зазначений у її операнде, тобто на мітку B50.

 

Завдання 2.

В MASMнаписать программу решения задачи. Создать EXE и COM модули.

Даны натуральное число n, целые числа a1, …, an. Найти наибольшее из нечетных чисел и количество четных чисел, входящих в последовательность a1, …, an, an+1.

assume CS:code, DS:Data

code segment

begin: mov ax,data

mov ds,ax

 

mov bl,2 ;будем делить на 2

 

mov ax,0 ;обнуляем регистры

mov si,-1

 

ii: inc si ;

cmp si,len ;сравниваем текущий индекс с длиной массива

je fin ;если они равны то мы прошли весь массив и идем на вывод

;иначе идем дальше

 

mov al,mas1[SI] ;записываем в al текущий элемент массива

div bl ;делим его 2

 

cmp ah,0 ;если остача = 1(елемент не парный),

jne jj ;то переходим к следующему елементу

inc kol

jmp ii

 

jj: mov al,mas1[SI]

cmp max,al ;иначе сравниваем текущий елемент с минимальным

ja ii ;если он больше, то переходим к след елементу

 

mov max,al ;иначе записываем в min текущий елемент

jmp ii

fin: mov bl,10 ;вывод на екран минимального елемента

xor ax,ax

mov al,max

 

div bl

 

add al,48

add ah,48

mov bl,ah

 

mov y,al

mov ah,09h

mov dx,offset y

int 21h

 

mov y,bl

mov ah,09h

mov dx,offset y

int 21h

 

mov al,10 ;вывод перевода строки

mov y,al

mov ah,09h

mov dx,offset y

int 21h

 

mov al,kol

add al,48

mov y,al

mov ah,09h

mov dx,offset y

int 21h

 

exit:

mov ah,4ch

int 21h

code ends

data segment

max db 0 ;мин ел изначально равен большому числу

kol db 0

len dw 10 ;к-во ел в массиве

mas1 db 10,24,18,9,56,3,75,1,46,35 ;

y db " $"

data ends

stk segment stack

db 256 dup()

stk ends

end begin

 

 

Завдання 3

В матрице С(n,n) удалить в каждом столбце минимальный элемент столбца.

 

assume CS:code, DS:Data

code segment

begin: mov ax,data

mov ds,ax

 

mov bx,row

mov ax,col

mul bx

sub ax,col

mov dob,ax

 

mov bl,mas1

mov min,bl

mov cx,col

 

incCol:

push cx

 

mov di,cx

dec di

mov cx,row

 

mov min,254

 

incRow:

mov si,cx

dec si

mov bx,col

mov ax,si

mul bx

mov bx,ax

mov al,mas1[bx][di]

 

cmp min,al

jb less

mov min,al

mov ind,si

 

less: loop incRow

mov si,ind

dec si

ii: inc si

cmp si,row

je jj

 

mov bx,col

mov ax,si

mul bx

mov bx,ax

add bx,col

mov al,mas1[bx][di]

sub bx,col

mov mas1[bx][di],al

jmp ii

 

jj: pop cx

loop incCol

 

 

mov si,0

mov DI,0

dec col

fin: mov bl,10

xor ax,ax

mov al,mas1[DI]

div bl ;делим число на 10

 

add al,48 ;добавляем к младшей части 48, чтобы на вывод шел символ числа

add ah,48 ;добавляем к старшей части 48

mov bl,ah

 

mov y,al ;выводим младшую часть

mov ah,09h

mov dx,offset y

int 21h

 

mov y,bl ;выводим старшую часть

mov ah,09h

mov dx,offset y

int 21h

 

mov bl,0 ;после каждого елемента выводим пробел

mov y,bl

mov ah,09h

mov dx,offset y

int 21h

cmp si,col

jne s

 

mov bl,10 ;после каждых col елементов выводим перевод строки

mov y,bl

mov ah,09h

mov dx,offset y

int 21h

mov si,-1

s: inc si

inc DI

cmp DI,dob

jne fin

 

mov ax,4c00h

int 21h

code ends

data segment

row dw 4

col dw 5

dob dw 1

min db 0

ind dw 0

mas1 db 61,31,13,99,1

db 11,22,6, 11,9

db 8, 12,5, 9,5

db 12, 3,12, 1,6

 

y db " $"

msg db ?

data ends

stk segment stack

db 256 dup()

stk ends

end begin