Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
шпоргалки_все.docx
Скачиваний:
3
Добавлен:
24.09.2019
Размер:
59.71 Кб
Скачать

19. Интерфейс модулей, написанных на языке ассемблера с модулями, написанными на языке с.

Команды ассемблера в тексте программы на C без изменения вкл. в формируемый компилятором код. Для встроенного ассемблера разр. использовать: - машинные команды; строковые команды; - все инструкции передач управления с прямой или косвенной адресацией; - директивы описания и определения данных. Нельзя исп. директивы, управляющие его работой: ASSUME,SEGMENT,ENDS,PROC,ENDP,ORG и т.д. а также имя группы DGROUP, имена сегментов _TEXT,_STACK,_DATA и т.п. Можно ссылаться на описанные в С переменные. Группа инструкций, заключенная в фигурные скобки, не требует повторения перед каждой из них ключевого слова “asm”.

#include <iostream.h>

#progme inline

asm v1 dw 10

asm v2 dw 90

void main(void)

{unsigned i;

again:

asm {mov ax,v2

add ax,v1

push ax

mov i,ax

}

printf(“i=%d”,i);

if(i>190)

asm jmp _end_

else if (i==150)

asm {

mov ah,2

mov dl,7

int 21h

}

asm {

pop ax

mov v2,ax

jmp again

}

_end_:

puts(“конец проги”);

}

20. Вызов из программы, написанной на языке С , процедур, написанных на ассемблере.

Общая схема: 1) Процедуры на asm и C объединяются совместно, используя файл-проект. В этом случае перечисляются C функции и имена объектных модулей, написанных на asm после трансляции их с помощью TASM. 2) Компиляция из командной строки: а) выполнить трансляцию модуля на С; б) выполнить трансляцию модуля на ассемблере; в) выполнить объединение объектных модулей. ASM процедура должна удовлетворять ниже перечисленным требованиям: - гарантировать получение необходимой информации редактором связей; - обеспечить получ. значений аргументов, переданных ей при вызове, и видимость всех внешних переменных; - должно собл. соотв. моделей памяти, используемых при компиляции C-функции и при обработке asm процедур. В этой связи ассемблерная процедура должна: а) использовать правило именования сегментов, принятое в С; б) явно описывать все глобальные и внешние идентификаторы; в) поддерживать принятую в С посл. передачи аргументов и возврата значений в точку вызова. Все внешние переменные, на которые ссылается ассемблерная процедура. и описанные в С-функциях как внешние, должны объявляться в asm блоке явно с исп. директивы extrn имя_переменной: тип. Если имеются переменные, описанные в ассемблерном модуле, значения которых исп. в С функции. то они в asm модуле объявляются с атрибутом public.

C_asm.cpp

extern void asm f1(int *i1,int *i2,unsigned long l);

void main (void)

{int i=5,j=7;

unsigned long l=0x12345678;

asm_f1(&I,&j,l);

printf(“i=%d,j=%d,l=%lx/n”,i,j,l); }

Вызов процедуры аsm

.model small .code

public asm_f1

asm_f1 PROC near

push bp

mov bp,sp

push si,di

mov si,[bp+4]

mov di,[bp+6]

mov bx,[bp+8]

mov ax,[bp+10]

mov cx,[si]

xchg cx,[di]

mov [si],cx

pop di si

pop bp

ret

asm_f1 endp

end

21. Вызов из ассемблерной программы функций на языке С.

Для каждой прогаммы нужно указать, какие переменные она передаёт в другой модуль и какие переменные она получает из другого модуля.

Фкнкция С++ должна быть описанна в асм. после дерективы EXTERN.

Описание глобальных переменных происходит следующим образом:

-если она обявлена в асм., то должна иметь атрибут PUBLIC а в С++ - EXTERN

-если она обявлена в С++ как внешняя, тогда в асм. она должна иметь атрибут EXTERN

Если функция на С++ возрващает 16-битное значение(char,short,int,enum) то оно будет помещенов регистр АХ, если 32-битное(long) - то DX:AX причём старшая часть в DX

22. Использование встроенного ассемблера.

Необходимо задать дерективу #pragma inline

Асм. команду записывают в виде asm код_операции операнды (;) или (новая строка)

код_операции - (mov,xor...) Если необходимо задать много асм. команд, то они заключаются в фигурные скобки.

Коментарии ожно записывать только в форме, принятой в языке С++.

21. Транспонирование матрицы заданной в кодовом сегменте.

.model small

.stack 100h

.code

start:

jmp continue ; оставить место для матрицы

razmer equ 4

matrix dw 1,2,3,4

dw 5,6,7,8

dw 9,10,11,12

dw 13,14,15,16

continue:

push cs

pop ds ; направляем ds на сегмент кода

mov si,2 ; si - указывает на matrix[0][1]

mov bx,razmer ; в bx - размер матрицы

shl bx,1 ; bx=bx*2, то есть bx указывает на matrix[1][0]

mov ax,bx ; в ax - смещение, равное длине строки

mov cx,razmer ; в cx - razmer

dec cx ; количество перестановок на 1 меньше, чем размер матрицы

loop1: ; внешний цикл по строкам

push cx ; сохранить cx в стеке

loop2: ; внутренний цикл по столбцам (выше главной диагонали)

mov dx,matrix[bx] ; в dx - элемент ниже диагонали

mov di,matrix[si] ; в di - элемент выше диагонали

mov matrix[bx],di ; переставляем их

mov matrix[si],dx

add si,2 ; смещаемся вправо

add bx,ax ; смещаемся вниз

loop loop2 ; цикл повторяется cx раз

pop cx ; восстанавливаем сохраненное cx

push ax ; сохраняем в стеке длину строки

mov ax,razmer ; вычисляем, на сколько сместиться, чтобы оказаться

sub ax,cx ; главной диагональю

inc ax

shl ax,1

add si,ax ; смещаемся на matrix[i][i+1], i - номер очередного ци

mov bx,si ; уставнавливаем bx на si

pop ax ; восстанавливаем длину строки

add bx,ax ; смещаем bx на строку вниз

sub bx,2 ; и на 1 элемент назад

loop loop1 ; цикл, пока cx != 0

mov ah,4ch

int 21h

end start

22. Ввод символа. Определить его позицию в строке и вывести на экран

.model small

.stack 100h

.data

stroka db 80 dup(?),'$'

symb db ?,' ','$' ; можно и не выделять память для символа

msg_in db 0ah,0dh,"Vvedite simvol:",0ah,0dh,"$"

msg db 0ah,0dh,"Simvol ","$"

msg1 db "nayden! Ego index - ","$"

msg_err db "ne nayden.","$"

c10 dw 10

.code

start:

mov ax,@data

mov ds,ax

xor bx,bx ; в bx - индекс вводимого символа

input_loop:

mov ah,01h ; считываем символ

int 21h

cmp al,13 ; если это enter

je for_find ; то конец ввода

mov stroka[bx],al ; иначе записываем символ в строку

cmp bx,80 ; если ввели 80 символов

je for_find ; то конец ввода

inc bx ; увеличиваем bx

jmp input_loop

for_find:

lea dx,msg_in ; вывод msg_in

mov ah,09h

int 21h

mov ah,01h ; ввод нужного символа

int 21h

mov byte ptr symb,al ; сохраняем его в symb ( можно использовать любой из свободных регистров, если хошь)

mov cx,bx ; в cx - длина строки

xor bx,bx ; bx - индекс элемента

mov ah,byte ptr symb ; в ah - нужный символ

find:

cmp ah,stroka[bx] ; сравниваем текущий элемент с нужным симв

je found ; если совпадают, то jmp на found

inc bx ; переход к следующему элементу

loop find ; цикл повторяется cx раз

lea dx,msg ; если символ не найден, то

mov ah,09h ; вывод msg

int 21h

lea dx,symb ; вывод самого символа

int 21h

lea dx,msg_err ; вывод msg_err

int 21h

jmp end_program ; завершить программу

found: ; если найден символ

lea dx,msg ; вывод msg

mov ah,09h

int 21h

lea dx,symb ; вывод самого символа

int 21h

lea dx,msg1 ; вывод msg1

int 21h

mov ax,bx ; сохраняем индекс в ax

xor cx,cx ; cx - счетчик цифр

number_to_string:

xor dx,dx ; подготовка к делению

div c10 ; деление

add dx,30h ; в dx - ASCII-код остатка от деления

push dx ; сохраняем его в стеке

inc cx ; инкремент счетчика цифр

cmp ax,0 ; цикл, пока частное ненулевое

jne number_to_string

out_index_loop: ; цикл вывода индекса

pop dx ; извелекаем очередную цифру

mov ah,02h ; выводим ее на экран

int 21h

loop out_index_loop

end_program:

mov ah,4ch

int 21h

end start

25.Ввод с клавиатуры и умножение длинных чисел

.model small

.stack 100h

.data

num1 dd 0

num2 dd 0

proizv dd 0,0

msg1 db 0ah,0dh,"Vvedite pervoe chislo:",0ah,0dh,"$"

msg2 db 0ah,0dh,"Vvedite vtoroe chislo:",0ah,0dh,"$"

c10 dw 10

.code

start:

mov ax,@data

mov ds,ax

lea dx,msg1 ; вывод на экран msg1

mov ah,09h

int 21h

call input ; ввод первого числа

lea bx,num1 ; записываем введенное длинное число в num1:

mov word ptr[bx],si ; младшее слово

mov word ptr[bx+2],di ; старшее слово

lea dx,msg2 ; вывод на экран msg2

mov ah,09h

int 21h

call input ; ввод второго числа

lea bx,num2 ; записываем введенное длинное число

mov word ptr[bx],si

mov word ptr[bx+2],di

mov ax,word ptr num1 ; перемножение чисел (смотри конспект)

mul word ptr num2

mov word ptr proizv,ax

mov word ptr proizv+2,dx

mov ax,word ptr num1

mul word ptr num2+2

add word ptr proizv+2,ax

adc word ptr proizv+4,dx

mov ax,word ptr num1+2

mul word ptr num2

add word ptr proizv+2,ax

adc word ptr proizv+4,dx

mov ax,word ptr num1+2

mul word ptr num2+2

add word ptr proizv+4,ax

adc word ptr proizv+6,dx

mov ah,4ch

int 21h

input proc ; процедура ввода длинного числа

xor si,si ; возвращает число в di:si

xor di,di

loop1:

mov ah,01h

int 21h

cmp al,13

je end_input

sub al,30h

xor bx,bx

mov bl,al

mov ax,di

mul c10

mov di,ax

mov ax,si

mul c10

add ax,bx

adc dx,di

mov di,dx

mov si,ax

jmp loop1

end_input:

ret

input endp

end start

26. Обработка переполнения при делении чисел. Числа ввести с клавиатуры

Используя команды DIV и особенно IDIV, очень просто вызвать

пеpеполнение. Прерывания приводят (по крайней мара в системе, используемой

при тестировании этих программ) к непредсказуемым результатам. В операциях

деления предполагается, что частное значительно меньше, чем делимое.

Деление на ноль всегда вызывает прерывание. Но деление на 1 генерирует

частное, которое равно делимому, что может также легко вызвать прерывание.

Рекомендуется использовать следующее правило: если делитель - байт,

то его значение должно быть меньше, чем левый байт (AH) делителя: если

делитель - слово, то его значение должно быть меньше, чем левое слово (DX)

делителя. Проиллюстрируем данное правило для делителя, равного 1:

Операция деления: Делимое Делитель Частное

Слово на байт: 0123 01 (1)23

Двойное слово на слово: 0001 4026 0001 (1)4026

В обоих случаях частное превышает возможный размер. Для того чтобы

избежать подобных ситуаций, полезно вставлять перед командами DIV и IDIV

соответствующую проверку. В первом из следующих примеpов предположим, что

DIVBYTE - однобайтовый делитель, а делимое находится уже в регистре AX. Во

втором примере предположим, что DIVWORD - двухбайтовый делитель, а делимое

находится в регистровой паре DX:AX.

Слово на байт Двойное слово на байт

CMP AH,DIVBYTE CMP DX,DIVWORD

JNB переполнение JNB переполнение

DIV DIVBYTE DIV DIVWORD

Для команды IDIV данная логика должна учитывать тот факт, что либо

делимое, либо делитель могут быть отрицательными, а так как сравниваются

абсолютные значения, то необходимо использовать команду NEG для временного

перевода отрицательного значения в положительное.

27. Дана строка в сегменте кода. Отсортировать методом выборки

.model small

.stack 100h

.code

start:

jmp continue

stroka db 254, 0 dup(255)

continue:

push cs

pop ds ; направляем ds на сегмент кода

mov bx,2

xor dx, dx

mov ah, 0Ah

int 21h

mov ah, 0dh

xor di,di

loop1:

mov al,stroka[bx]

cmp ah,stroka[bx+1] ; проверка, конец строки или нет

je end_program

mov si,bx

inc si

loop2: ; поиск

cmp ah,stroka[si]

je end_loop1

cmp al,stroka[si]

jna next_iter ; поиск

mov al,stroka[si] ; минимального

mov di,si ; элемента

next_iter:

inc si

jmp loop2

end_loop1:

mov dh,stroka[bx] ;перестановка

mov stroka[bx],al ;

mov stroka[di],dh

inc bx

jmp loop1

end_program:

mov ah,09h

lea dx,stroka

int 21h

mov ah,4ch

int 21h

end start

28 Транспонировать битовую матрицу использую операторы сдвига.

.model small

.stack 100h

.data

mes1 db 10,13,"Vvedite elementy matricy(8 elem)!!$"

mes2 db 10,13,"$"

mas db 8 dup(0)

mas_tr db 8 dup(0)

.code

begin:

mov ax,@data ;перемещаем сегмент данных в ах

mov ds,ax ;перемещаем сегмент данных в dx

lea dx,mes1 ;в dx адрес mes1

mov ah,9h ;вывод строкм mas1

int 21h

xor bx,bx

mov cx,8

again: ;ввод массива

mov ah,1

int 21h

sub al,'0'

mov mas[bx],al

inc bx

loop again ;повторение цикла again, пока сх не = 0

lea dx,mes2 ;адрес mes2 в dX

mov ah,9

int 21h

mov cx,8

xor bx,bx

xor dh,dh

output: ; вывод матрицы

mov dl,mas[bx]

add dx,30h

mov ah,2

int 21h

inc bx

loop output

mov cx,8

lea di,mas_tr

repeat: ;транспонирование

push cx

mov cx,8

lea si,mas

rep1:

rol BYTE PTR[si],1

rcl al,1

inc si

loop rep1

pop cx

mov [di],al

inc di

loop repeat

exit:

mov ah,4с00h

int 21h end begin

29. В сегменте данных дана матрица. Отсортировать ее побочную дигональ

.model small

.stack 100h

.data

razmer equ 4

matrix dw 1,2,3,13

dw 5,6,10,8

dw 9,7,11,12

dw 4,14,15,16

.code

start:

mov ax,@data

mov ds,ax

mov cx,razmer

dec cx

mov bx,cx

shl bx,1 ; bx - смещение (длина строки -2)

loop1:

mov si,bx

push cx

loop2:

mov dx,matrix[si] ;

mov di,matrix[si][bx] ; перестановка

cmp dx,di ;

jl cont_loop2

mov matrix[si],di

mov matrix[si][bx],dx

cont_loop2:

add si,bx ;

loop loop2 ; смещение на следующую строку

pop cx ;

loop loop1

lea dx,matrix

mov ah,4ch

int 21h

end start

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

; Отсортировать элементы главной диагонали матрицы.

;

; 18.06.04

;

.model small

.stack 300h

.data

N equ 4 ; РАЗМЕР МАТРИЦЫ

THE_MATRIX db 'C', '1', '1', '1'

db '2', 'B', '2', '2'

db '3', '3', 'A', '3'

db '4', '4', '4', 'W','$'

str1 db 0dh,0ah,'$'

str2 db ' $'

.code

program:

mov ax, @data

mov ds, ax

mov cx, N

mov si, offset THE_MATRIX

push cx

mov cx, N

dec cx

;;;обычная сортировка пузырьком

sort_loop:

mov bx, si

add bx, N

inc bx

push cx

cmp_loop:

mov al, [si]

cmp al, [bx]

jna cont

mov dl, byte ptr [bx]

mov byte ptr [bx], al

mov byte ptr [si], dl

cont:

add bx, N

inc bx

loop cmp_loop

pop cx

add si, N

inc si

loop sort_loop

;;; Вывод матрицы

lea si,THE_MATRIX

mov cx,0

w3:

push cx

mov cx,0

w1:

mov ah,2

mov dx,[si]

int 21h

mov ah,9

lea dx,str2

int 21h

inc cx

cmp cx, n

je w2

inc si

jmp w1

w2:

mov ah,9

lea dx,str1

int 21h

inc si

pop cx

inc cx

cmp cl,n

jne w3

exit:

mov ax, 4c00h

int 21h

end program

30. Найти сумму элементов четных строк матрицы.

.model small

.stack 100h

.data

mes1 db 10,13,"Vvedite elementy matricy(5*4)!!$"

mes3 db 10,13,"Suuma 4etnyx strok(5*4):$",10,13

mes2 db 10,13,"$"

mas db 20 dup(0)

sum dw 5 dup(0)

.code

begin:

mov ax,@data

mov ds,ax

lea dx,mes1

mov ah,9h

int 21h

xor bx,bx

mov cx,20

again:

mov ah,1

int 21h

sub al,'0'

mov mas[bx],al

inc bx

loop again

lea dx,mes2

mov ah,9

int 21h

mov cx,20

xor bx,bx

xor dh,dh

output:

mov dl,mas[bx]

add dx,30h

mov ah,2

int 21h

inc bx

loop output

xor cx,cx

mov cl, 4 ;4islo strok

lea bx,mas ;adres matricy

add bx,4 ;perexod na 4etnuju str

mov si,0

p2: push cx

mov di,0

xor dx,dx ; dlja xranenija summy

mov cx,4 ; kol-vo stolbcov

p1:

mov al,[bx+di]

cbw

add dx,ax

inc di

loop p1

mov sum[si],dx

add si,2

add bx,8 ;na sled 4etnuju stroku

pop cx

dec cx

loop p2

xor dx,dx

lea dx,mes3

mov ah,9

int 21h

mov dx,sum[0]

add dx,30h

mov ah,09h

int 21h

mov dx,sum[2]

add dx,30h

mov ah,09h

int 21h

exit:

mov ah,4ch

int 21h

end begin

31 Ввести массив чисел, найти min и max, вывести на экран

.model small

.stack 100h

.data

massiv dw 80 dup(?)

msg1 db 0ah,0dh,"Vvodite chisla ",0ah,0dh,"$"

msg2 db 0ah,0dh,"max = $"

msg3 db 0ah,0dh,"min = $"

c10 dw 10

.code

start:

mov ax,@data

mov ds,ax

mov ah,09h ; вывод приглашения для ввода чисел

lea dx,msg1

int 21h

mov di,0 ; в di - max

mov si,32767 ; в si - min

xor dx,dx ; в dx - очередное число

input_loop:

mov ah,01h ; ввод символа

int 21h

cmp al,0dh ; если enter

je chislo ; то занести число в массив

cmp al,20h ; если пробел

je chislo ; то занести число в массив

sub al,30h ; вычитаем '0'

mov cl,al ; сохраняем цифру в cl

mov ax,dx ; в ax - введенное число

mul c10 ; умножаем на 10

xor ch,ch

add ax,cx ; добавляем цифру из al

mov dx,ax ; число снова в dx

jmp input_loop

chislo:

mov bx,cx ; в bx - порядковый номер очередного числа

shl bx,1 ; теперь - смещение очередного числа в массиве

mov massiv[bx],dx ; записываем в массив число

inc cx ; увеличиваем счетчик введенных чисел

cmp dx,si ; сравниваем число с минимальным

jb minimum ; если оно меньше, то jmp на minimum

cmp dx,di ; сравниваем число с максиальным

jg maximum ; если оно больше, то jmp на maximum

jmp chislo_cont ; иначе jmp на chislo_cont

minimum:

mov si,dx ; запоминаем минимальное число в si

jmp chislo_cont

maximum:

mov di,dx ; запоминаем максимальное число в di

chislo_cont:

xor dx,dx ; dx в ноль

cmp cx,80 ; если ввели 80-ое число

je end_input ; то конец ввода

cmp al,0dh ; если был нажат enter

je end_input ; то конец ввода

jmp input_loop

end_input:

mov ah,09h ; вывод на экран msg2

lea dx,msg2

int 21h

mov ax,di ; передаем в функцию output max через ax

call output ; выводим это число

lea dx,msg3 ; вывод на экран msg3

mov ah,9

int 21h

mov ax,si ; передаем в ouptput min через ax

call output ; выводим это число

mov ah,4ch ; завершение программы

int 21h

output proc ; процедура вывода числа, находящегосы в ax

xor cx,cx ; счетчик цифр

div_loop:

xor dx,dx ; подготовка к делению

div c10 ; деление

add dx,30h ; в dx - ASCII-код остатка от деления

push dx ; сохраняем его в стеке

inc cx ; инкремент счетчика

cmp ax,0 ; деление, покуда частное не нулевое

je out_loop

jmp div_loop

out_loop: ; цикл вывода числа

pop dx ; извлекаем из стека очередной остаток

mov ah,02h ; и выводим его на экран

int 21h

loop out_loop ; цикл продолжается cx раз

ret

output endp

end start

32. В сегменте данных расположены числа в формате двойного слова. С клавиатуры вводится число и определяется, имеется ли это число в сегменте данных.

.model small

.stack 100h

.data

massiv dd 12345678,13579246,24681357

chislo dd 0

c10 dw 10

str1 db 0ah,0dh,"Vvedite chislo:",0ah,0dh,'$'

str2 db 0ah,0dh,"Vvedennoe chislo ne naydeno.",0ah,0dh,'$'

str3 db 0ah,0dh,"Vvedennoe vami chislo naydeno!",'$'

.code

.386

start:

mov ax,@data

mov ds,ax

mov ah,09h

lea dx,str1

int 21h

input_loop:

mov ah,01h

int 21h

cmp al,0dh

je end_input

sub al,30h

xor bx,bx

mov bl,al

xor dx,dx ; ввод длинного числа

mov ax,word ptr[chislo+2]

mul c10

mov word ptr[chislo+2],ax

mov ax,word ptr[chislo]

mul c10

add dx,word ptr[chislo+2]

add ax,bx

mov word ptr[chislo],ax

mov word ptr[chislo+2],dx

jmp input_loop

end_input:

mov cx,offset chislo ; в сх - количество чисел

sub cx,offset massiv

shr cx,2

mov ax,word ptr[chislo] ; в ax - младшее слово числа

mov dx,word ptr[chislo+2] ; в dx - старшее слово числа

cmp_loop: ; цикл сравнения

mov bx,cx

dec bx

shl bx,2

add bx,offset massiv

cmp ax,word ptr[bx]

je continue_cmp

jmp cmp_end

continue_cmp:

add bx,2

cmp dx,word ptr[bx]

je find

cmp_end: ; если ничего не найдено

loop cmp_loop

mov ah,09h

mov dx,offset str2

int 21h

jmp end_start

find: ; если число найдено

mov ah,09h

mov dx,offset str3

int 21h

end_start:

mov ah,4ch

int 21h

end star

33. Ввести массив чисел и отсортировать методом пузырька

.model small

.stack 100h

.data

massiv dw 80 dup(?)

msg db "Vvodite chisla cherez probel, okonchanie vvoda - ENTER",0ah,0dh,'$'

c10 dw 10

.code

start:

mov ax,@data

mov ds,ax

mov ah,09h ; вывод msg

lea dx,msg

int 21h

xor bx,bx ; bx - смещение в массиве вводимого числа

xor dx,dx ; dx - вводимое число

input_loop:

mov ah,01h ; считваем очередной символ

int 21h

cmp al,0dh ; если это enter

je chislo

cmp al,20h ; или пробел

je chislo

sub al,30h ; иначе - получаем цифру

mov cl,al ; сохраняем ее в cl

mov ax,dx ; в ax - вводимое число

mul c10 ; умножаем на 10

xor ch,ch

add ax,cx ; добавляем к результату последнюю цифру

mov dx,ax ; в dx - полученное число

jmp input_loop

chislo: ; если окончен ввод числа

mov massiv[bx],dx ; запись этого числа в массив

add bx,2 ; смещаемся к следующему элементу

cmp bx,160 ; если массив заполнен

je end_input ;

cmp al,0dh ; или последнее число

je end_input ; то конец ввода

xor dx,dx ; обнуляем dx для ввода следующего числа

jmp input_loop

end_input:

mov cx,bx ; в cx - (количество введенных чисел + 1) * 2

shr cx,1 ; cx = cx \ 2

dec cx ; теперь в cx - количество введенных чисел

call sort ; сортировка

mov ah,4ch

int 21h

sort proc

loop1:

xor bx,bx ; bx - смещение в массиве

push cx ; сохраняем cx в стеке

loop2:

mov ax,massiv[bx]

cmp ax,massiv[bx][2] ; сравниваем два соседних элемента

jl cont_loop2 ; если правый больше левого, то продолжить цикл

mov dx,massiv[bx][2] ; иначе - перестановка

push massiv[bx][2]

push massiv[bx]

pop massiv[bx][2]

pop massiv[bx]

cont_loop2:

add bx,2 ; смещаемся к следующему элементу в массиве

loop loop2

pop cx ; восстанавливаем cx

loop loop1

ret

sort endp

end start

34.Вывести строку в обратном порядке.

.model small

.stack 100h

.data

msg1 db 0Ah,0Dh,"Enter string <80(char)",0Ah,0Dh,'$'

string db 80 dup(?)

msg2 db 0Ah,0Dh,"Reversing string",0Ah,0Dh,'$'

.code

start: mov ax,@data

mov ds,ax

lea dx,msg1

mov ah,09h

int 21h

mov cx,80

xor si,si

l1: mov ah,01h

int 21h

cmp al,0Dh

je continue

mov string[si],al

inc si

loop l1

continue: mov ah,09h

lea dx,msg2

int 21h

cmp si,0

je exit

dec si

mov cx,si

l2: mov si,cx

mov dl,string[si]

mov ah,02h

int 21h

loop l2

mov dl,string[0]

mov ah,02h

int 21h

exit:

mov ah,4Ch

int 21h

end start

35. Ввести с клавиатуры массив чисел. Найти суммы положительных и отрицательных чисел. Вывести результат.

.model small

.stack 256

.data

mas dw 8 dup(0)

zz db 0Dh, 0Ah,'-$'

.code

start:

mov ax,@data

mov ds,ax

mov cx,8

mas_in:

xor bx,bx

num_s_in:

cmp bx,6

je end_num_s_in

mov ah,01h

int 21h

cmp al,0Dh

je end_num_s_in

inc bx

xor ah,ah

push ax

jmp num_s_in

end_num_s_in:

mov bp,1

xor di,di

num_p:

cmp bx,1

je end_num_p

pop ax

sub al,'0'

mul bp

add di,ax

mov ax,bp

mov bp,10

mul bp

mov bp,ax

dec bx

jmp num_p

end_num_p:

pop ax

cmp al,'-'

jne ee

neg di

ee:

mov ax,cx

;sub ax,2

shl ax,1

mov si,offset mas

add si,ax

mov word ptr [si],di

loop mas_in

____SOBSTVENNO SLOGENIE____

mov di,offset mas

xor ax,ax ;summa bolhih 0

xor bx,bx ;summa menshih 0

mov cx,9

add_num:

cmp word ptr[di],0

jl add_less_zero

add ax,word ptr [di]

jmp e

add_less_zero:

add bx,word ptr [di]

e:

add di,2

loop add_num

___VYVOD_______

div_num_s:

mov cx,10

xor bp,bp

div_num:

cmp ax,0

je end_div_num

xor dx,dx

div cx

add dx,'0'

push dx

inc bp

jmp div_num

end_div_num:

vyvod:

cmp bp,0

je end_vyvod

pop ax

mov ah,02h

mov dl,al

int 21h

dec bp

jmp vyvod

end_vyvod:

cmp bx,0

je exit

neg bx

mov ah,9

mov dx,offset zz

int 21h

mov ax,bx

xor bx,bx

jmp div_num_s

exit:

mov ax,4C00h

int 21h end start

36.Дан массив строк. Найти строку с max длинной и вывести ее на экран.

.model small

.stack 100h

.data

str0 db "Hello",'$'

str1 db "Good day",'$'

str2 db "Hi!",'$'

str3 db "How do you do?",'$'

str4 db "I greet you",'$'

StrArray dw offset str0

dw offset str1

dw offset str2

dw offset str3

dw offset str4

StrCount dw 5

.code

program:

mov ax, @data

mov ds, ax

mov si, offset StrArray ; si - начало массива строк

mov cx, StrCount ; инициализация счетчика

xor ax, ax ; в ax - макс. длина строки

calc_length:

mov bx, [si] ; bx - смещение текущей строки

add si, 2 ; si сдвигается на следующую строку

push cx ; сохраняем счетчик

call str_len ; определяем длину строки

cmp ax, cx

ja end_loop ; если найденная длмна больше макс.

mov ax, cx ; сохраняем эту длину в ax

mov dx, bx ; сохраняем в dx смещение строки

end_loop:

pop cx ; восстанавливаем счетчик

loop calc_length

mov ah, 9 ; выводим макс. строку на экран

int 21h

mov ax, 4c00h

int 21h

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

; Находит длину строки

; bx - смещение строки

; Результат: cx - искомая длина

str_len proc near

push bx

push ax

xor cx, cx

mov al, '$'

mov ah, 0

len_lp:

cmp al, [bx]

je end_len

cmp ah, [bx]

je end_len

inc cx

inc bx

jmp len_lp

end_len:

pop ax

pop bx

ret

str_len endp

end program

37. Перевод числа из одной системы счисления в другую. Данные вводить с клавиатуры.

.modl small

.stack 256

.data

Mess1 db 'Enter number in 10c: $'

Mess2 db 0Dh, 0Ah,'Result in 16c: $'

.code

start:

mov ax,@data

mov ds,ax

mov ah,9

mov dx,offset Mess1

int 21h; Выводим первое сообщение

xor bx,bx

num_in:

; Вводим символы числа, пока не нажмется энтэр

mov ah,01h

int 21h

cmp al,0Dh

je end_num_in

sub al,'0' ; переводим в десятичный вид

xor ah,ah

push ax ; и ложим его в стек

inc bx

jmp num_in

end_num_in:

mov cx,1

num_preobr:

cmp bx,0

je end_num_preobr ; если цифры ;числа закончились, то переходим на ;end_num_preobr

pop ax

xor dx,dx ; умножаем на число в cx (1, 10, 100, 1000, …)

mul cx

; и добавляем к конечному числу

add di,ax

dec bx

; умножаем на 10, чтобы получить 10, 100, 1000, …

mov ax,10

mul cx

mov cx,ax

jmp num_preobr

end_num_preobr:

; Выводится сообщение 2

mov ah,9

mov dx,offset Mess2

int 21h

; начало коныертации в 16 систему

mov ax,di

mov bx,0

mov cx,16

num_convert:

; непосредственно перевод

cmp ax,0

je end_convert

xor dx,dx

; делим на систему счисления

div cx

; сравниваем остаток от деления с 9, если больше, добавляем ‘7’, иначе ‘0’

cmp dx,9

ja above_9

add dx,'0'

jmp next

above_9:

add dx,'7'

next:

push dx

inc bx

jmp num_convert

end_convert:

out_num:

; если цифры закончились, то переходим ;на end_out_num

cmp bx,0

je end_out_num

pop dx

mov ah,02h

int 21h

dec bx

jmp out_num

end_out_num:

mov ax,4C00h

int 21h

end start

38.Вычислить сумму столбцов матрицы с полным вводом/выводом (программа типа exe)

.model small

.stack 300h

.code

endl macro

push ax dx

mov ah, 02h

mov dl, 0Ah

int 21h

mov dl, 0Dh

int 21h

pop dx ax

endm

outint macro value

local outint_l1, outint_l2

push ax bx cx dx

mov ax, value

mov bx, 10

xor cx, cx

outint_l1:

xor dx, dx

div bx

push dx

inc cx

cmp ax, 0

jne outint_l1

mov ah, 02h

outint_l2:

pop dx

add dl, '0'

int 21h

loop outint_l2

pop dx cx bx ax

endm

proc readint

push cx si bx dx

mov buf_str, 8

mov ah, 0Ah

lea dx, buf_str

int 21h

xor cx, cx

mov si, 2

xor ax, ax

mov bx, 10

in_loop:

mul bx

mov dl, [buf_str+si]

sub dl, '0'

add ax, dx

inc si

inc cl

cmp cl, [buf_str+1]

jl in_loop

pop dx bx si cx

endl

ret

endp

start:

mov ax, @data

mov ds, ax

xor cx, cx

xor dx, dx

xor di, di

input_loop:

push dx

mov ah, 09h

lea dx, str_1

int 21h

outint cx

lea dx, str_2

int 21h

mov si, sp

mov dx, [ss:si]

outint dx

lea dx, str_3

int 21h

call readint

mov word ptr matrix[di], ax

add di, 2

pop dx

inc cx

cmp cx, N

jl input_loop

xor cx, cx

inc dx

cmp dx, N

jl input_loop

xor ax, ax

cont_summ:

mov si, ax

shl si, 1

xor dx, dx

cont_summ_2:

add dx, word ptr matrix[si]

add si, N*2

cmp si, N*N*2

jl cont_summ_2

outint dx

endl

inc ax

cmp ax, N

jl cont_summ

mov ax, 4C00h

int 21h

.data

N equ 3

matrix db N*N*2 dup(?)

buf_str db 10 dup(?)

str_1 db "Input matrix[$"

str_2 db "][$"

str_3 db "]:",10,13,"$"

sum1 dw 0

sum2 dw 0

end start

39. Перевод строки в число.

.model small

.stack 100h

.data

num dw ?

c10 db 10

.code

begin:

mov ax,@data

mov ds,ax

xor bx,bx

again:

mov ah,1

int 21h

cmp al, 0dh ; если энтер, то закончим ввод

je con

sub al,'0' ; вычитаем ‘0’ из символа для

xor ah,ah ;

mov si,ax

mov ax,bx ; помещаем конечный на данный момент результат в ax

mul c10 ; и умножаем его на 10

add ax,si ; добавляем к полученному значению введенную только что цифру

mov bx, ax ; формируем в bx конечное на данный момент значение

jmp again ; зацикливаем

con:

mov num,bx ; полученное число

mov ax, 4c00h

int 21h

end begin

40. В сегменте данных дана матрица. Отсортировать ее побочную дигональ

.model small

.stack 100h

.data

razmer equ 4

matrix dw 1,2,3,13

dw 5,6,10,8

dw 9,7,11,12

dw 4,14,15,16

.code

start:

mov ax,@data

mov ds,ax

mov cx,razmer

dec cx

mov bx,cx

shl bx,1 ; bx - смещение (длина строки -2)

loop1:

mov si,bx

push cx

loop2:

mov dx,matrix[si] ;

mov di,matrix[si][bx] ; перестановка

cmp dx,di ;

jl cont_loop2

mov matrix[si],di

mov matrix[si][bx],dx

cont_loop2:

add si,bx ;

loop loop2 ; смещение на следующую строку

pop cx ;

loop loop1

lea dx,matrix

mov ah,4ch

int 21h

end start

41.Вводится матрица чисел. Найти сумму элементов по каждой диагонали и вывести на экран.

.model small

.stack 300h

.code

endl macro

push ax dx

mov ah, 02h

mov dl, 0Ah

int 21h

mov dl, 0Dh

int 21h

pop dx ax

endm

outint macro value

local outint_l1, outint_l2

push ax bx cx dx

mov ax, value

mov bx, 10

xor cx, cx

outint_l1:

xor dx, dx

div bx

push dx

inc cx

cmp ax, 0

jne outint_l1

mov ah, 02h

outint_l2:

pop dx

add dl, '0'

int 21h

loop outint_l2

pop dx cx bx ax

endm

proc readint

push cx si bx dx

mov [buf_str], 8

mov ah, 0Ah

lea dx, buf_str

int 21h

xor cx, cx

mov si, 2

xor ax, ax

mov bx, 10

in_loop:

mul bx

mov dl, [buf_str+si]

sub dl, '0'

add ax, dx

inc si

inc cl

cmp cl, [buf_str+1]

jl in_loop

pop dx bx si cx

endl

ret

endp

start:

mov ax, @data

mov ds, ax

xor cx, cx

xor dx, dx

xor di, di

input_loop:

push dx

mov ah, 09h

lea dx, str_1

int 21h

outint cx

lea dx, str_2

int 21h

mov si, sp

mov dx, [ss:si]

outint dx

lea dx, str_3

int 21h

call readint

mov word ptr matrix[di], ax

add di, 2

pop dx

inc cx

cmp cx, N

jl input_loop

xor cx, cx

inc dx

cmp dx, N

jl input_loop

xor si, si

xor ax, ax

count_sum1:

add ax, word ptr matrix[si]

add si, N*2+2

cmp si, N*N*2

jl count_sum1

mov sum1, ax

mov si, N*2-2

xor ax, ax

count_sum2:

add ax, word ptr matrix[si]

add si, N*2-2

cmp si, N*(N-1)*2+2

jl count_sum2

mov sum2, ax

mov ah, 09h

lea dx, str_4

int 21h

outint sum1

lea dx, str_5

int 21h

outint sum2

lea dx, str_6

int 21h

mov ax, 4C00h

int 21h

.data

N equ 3

matrix db N*N*2 dup(?)

buf_str db 10 dup(?)

str_1 db "Input matrix[$"

str_2 db "][$"

str_3 db "]:",10,13,"$"

str_4 db "Sum1=$"

str_5 db 10,13,"Sum2=$"

str_6 db 10,13,"$"

sum1 dw 0

sum2 dw 0

end start

42. Работа с окнами в текстовом режиме.

Работа с окнами в текстовом режиме. (результат работы проги: синее окно,

;в нем - зеленое окно, в зеленом окне - текст :))

.MODEL small

.STACK 100h

.DATA

str_ db 'TEXT'

len equ $-str_

.CODE

main:

mov ax, @data

mov ds, ax

mov es, ax

mov ah, 06h ;очистка окна

mov al, 00h ;режим окна

mov bh, 17h ;видео-атрибут для пустых строк

mov cx, 0000h ;очистка экрана от (00;00) до (24;79)

mov dx, 1b4fh

int 10h

mov ax, 0600h ;в ah - 06h в al - 00h

mov bh, 20h

mov cx, 0a1ch

mov dx, 0c31h

int 10h

mov ah, 13h ;вывод на экран в позиции курсора

mov al, 0 ;не менять положение курсора

mov bh, 0 ;номер страницы

mov bl, 07h ;цвет выводимого текста

mov cx, len

mov dx, 0b25h ;координаты на экране (dh - y, dl - x)

lea bp, str_ ;адрес выводимой строки

int 10h

mov ah, 4ch

int 21h

end main

43.Сложение и вычитание длинных чисел.

.model small

.stack 100h

.data

num1 dw 1234h, 5678h

num2 dw 8765h, 4321h

res1 dw 0,0

res2 dw 0,0

.code

start:

mov ax, @data

mov ds, ax

; сложение

mov ax, num1[0]

add ax, num2[0]

mov res1[0], ax

mov ax, num1[2]

adc ax, num2[2]

mov res1[2], ax

; вычитание

mov ax, num1[0]

sub ax, num2[0]

mov res2[0], ax

mov ax, num1[2]

sbb ax, num2[2]

mov res2[2], ax

mov ax, 4C00h

int 21h

end start

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]