Удаление строки в матрице 5х6 - Assembler
Формулировка задачи:
Требуется удалить строку в матрице, которая соответствует номеру введенному с клавиатуры.
Мне нужен алгоритм вывода массива по строкам, если он есть удалить строку не проблема.
Вот пример вывода по столбцам и удаление столбца пытался переделать - не смог. Ай нид сам хелп!
Только TASM!
.model small .stack 256h .data i_predel dw 6 j_predel dw 5 decol dw ? i dw 0 j dw 0 pos dw ? stroka db 'VVEDITE NOMER STOLBCA COTORII NADO UDALIT',10,13,'$' massive db 10,13,'PERVII MASSIV:',10,13,'$' otvet db 10,13,'VTOROU MASSIV',10,13,'$' mas db 1,2,3,4,5 db 1,2,4,1,7 db 4,3,8,7,5 db 5,4,3,7,7 db 1,2,3,4,5 db 5,4,1,7,4 .code Start: mov ax,@data mov ds,ax lea dx,stroka mov ah,09h int 21h mov ah,01h ; вводим номер столбца int 21h sub al,31h ; 30+1 для удобства ввода номера cbw mov decol,ax ; //// вывод первоначального массива mov ah,09h lea dx,massive int 21h go: ; i - строка ; j - столбец ; они равны нулю mov cx,j_predel ; вывод по столбцам m1: mov ax,j_predel mov bx,i mul bx ;количество_элементов_в_строке*i (так как размер элемента 1 байт можно не множить) mov pos,ax mov ax,pos mov bx,j add ax,bx ; (количество_элементов_в_строке*i )+j mov si,ax mov dl,mas[si] ; в si полученные координаты mas[i][j] mov ah,02h add dl,30h int 21h mov dl,20h ; пробел int 21h inc j ; переход на следующий столбец loop m1 mov j,0 ; вывели строку i обнуляем j mov ax,i mov dx,i_predel dec dx cmp ax,dx ; смотрим, не последняя ли строка если да то заканчиваем вывод массива jge start2 inc i mov ah,02h ;если нет переходим на следующую строку mov dl,10 int 21h jmp go ; // удаляем столбец start2: mov ah,09h lea dx,otvet int 21h mov i,0 ; все обнуляем mov j,0 go2: mov cx,j_predel dec cx ; столбцов будет -1 так как один из них мы удаляем m2: mov ax,j ; смотрим не данный ли столбец нам нужно удалить cmp ax,decol je m3 ; на заметку: {если будет введен номер несуществующего столбца (0,6,7...) удалится всегда последний столбец ; т.к. cx-1 а условие je не будет выполнено} jmp m4 m3: inc j ; если это так, прыгаем на следующий столбец m4: mov ax,j_predel ; дальше по аналогии с первой частью программы mov bx,i mul bx mov pos,ax mov ax,pos mov bx,j add ax,bx mov si,ax mov dl,mas[si] mov ah,02h add dl,30h int 21h mov dl,20h int 21h inc j loop m2 mov j,0 mov ax,i mov dx,i_predel dec dx cmp ax,dx jge exit inc i mov ah,02h mov dl,10 int 21h jmp go2 Exit: mov ax,4c00h int 21h end start
Решение задачи: «Удаление строки в матрице 5х6»
textual
Листинг программы
.model small .stack 256h .data step dw -1 stroka db 'VVEDITE NOMER STROKI COTORII NADO UDALIT',10,13,'$' massive db 10,13,'PERVII MASSIV:',10,13,'$' otvet db 10,13,'VTOROU MASSIV',10,13,'$' mas db 1,2,3,4,5 db 1,2,4,1,7 db 4,3,8,7,5 db 5,4,3,7,7 db 1,2,3,4,5 db 5,4,1,7,4 len dw $-mas .code Start: mov ax,@data mov ds,ax lea dx,stroka mov ah,09h int 21h mov ah,01h ; вводим номер строки int 21h sub ax,30h cbw push ax mov dx,offset massive call call_output mov dx,offset otvet pop step call call_output Exit: xor ax,ax int 16h mov ax,4c00h int 21h output: push bp mov bp,sp mov dx,[bp+8] mov ah,9 int 21h mov cx,[bp+6] mov si,[bp+4] xor di,di @1: mov cx,5 @2: inc di cmp di,step jnz @4 add si,5 jmp @3 @4: lodsb or al,30h int 29h mov al,20h int 29h loop @4 mov al,10 int 29h @3: cmp di,6 jnz @1 pop bp ret 6 call_output: push dx push len push offset mas call output ret end Start
Объяснение кода листинга программы
- В начале кода указывается модель памяти - small, что позволяет использовать 16-битные регистры и стек.
- Задаются начальные значения переменных:
step
устанавливается равным -1, что будет использоваться как счётчик для прохода по строке в обратном направлении.stroka
содержит строку, которую нужно удалить, и символы новой строки, пробела и символа доллара в конце строки.massive
содержит строку, которая будет выводиться вместо удаляемой строки.mas
содержит саму матрицу 5х6.len
содержит длину строки, которую нужно удалить.
- В блоке кода с меткой Start происходит ввод данных и вызов функции удаления строки:
- Вначале перенаправляется сегмент данных на сегмент, где расположены переменные.
- Затем происходит вывод строки для ввода номера строки.
- Пользователь вводит номер строки, и этот номер сдвигается на 30, чтобы его можно было использовать как числовое значение (от 0 до 29), соответствующее позиции строки в матрице.
- Номер строки сохраняется в переменной
ax
. - Вызывается функция
call_output
, которая выводит строку вместо удаляемой строки. - Выводится строка
VTOROU MASSIV
, которая будет заменять удаляемую строку. - Затем вызывается функция
call_output
для вывода строкиPERVII MASSIV
.
- Функция call_output:
- Вначале функция получает в качестве параметров адрес строки, длину строки и адрес матрицы.
- Затем происходит проход по строке в обратном направлении, начиная с 5-го символа (поскольку счётчик
di
начинается с -1), и выводится каждый символ строки. - После прохода по всей строке выводится символ новой строки.
- В функции call_output используется рекурсия:
- Если номер строки больше 0, то вызывается функция
call_output
для вывода строкиPERVII MASSIV
. - Если номер строки равен 0, то выводится строка
VTOROU MASSIV
. - Если номер строки меньше 0, то выводится символ новой строки.
- Если номер строки больше 0, то вызывается функция
- В функции call_output используется стек:
- Для хранения параметров функции используется стек.
- При вызове функции
call_output
в стек помещаются адрес строки, длину строки и адрес матрицы. - При возврате из функции
call_output
параметры извлекаются из стека.
- В функции call_output используется рекурсия и стек для реализации прохода по строке в обратном направлении.