Отправляет email-рассылки с помощью сервиса Sendsay
  Все выпуски  

RFpro.ru: Ассемблер? Это просто! Учимся программировать


Хостинг портала RFpro.ru:
Московский хостер
Профессиональный ХОСТИНГ на базе Linux x64 и Windows x64

РАССЫЛКИ ПОРТАЛА RFPRO.RU

Лучшие эксперты по данной тематике

Коцюрбенко Алексей aka Жерар
Статус: Профессор
Рейтинг: 2733
∙ повысить рейтинг »
Boriss
Статус: Академик
Рейтинг: 2636
∙ повысить рейтинг »
Абаянцев Юрий Леонидович aka Ayl
Статус: Профессионал
Рейтинг: 2117
∙ повысить рейтинг »

/ КОМПЬЮТЕРЫ И СОФТ / Программирование / Assembler (Ассемблер)

Номер выпуска:1475
Дата выхода:25.09.2011, 08:00
Администратор рассылки:Лысков Игорь Витальевич (Старший модератор)
Подписчиков / экспертов:200 / 62
Вопросов / ответов:1 / 1

Консультация # 184059: Уважаемые эксперты! Пожалуйста, ответьте на вопрос: Задание: Разделить элементы массива A на соответствующие элементы массива B и записать результат в массив B. Размерность вводится пользователем, и элементы также. Ошибка в том, что не могу понять как сделать разно-адресные массивы (чтобы запоминались элементы и первого массива и второг...


Консультация # 184059:

Уважаемые эксперты! Пожалуйста, ответьте на вопрос:
Задание:
Разделить элементы массива A на соответствующие элементы массива B и записать результат в массив B.
Размерность вводится пользователем, и элементы также.
Ошибка в том, что не могу понять как сделать разно-адресные массивы (чтобы запоминались элементы и первого массива и второго)
Пишу в Tasm, под 32 бит.
Код

Код :
model tiny

 .data
sGet db 'Enter matrix capacity: $'  ;приглашение для ввода размерности
sMatrix db 0ah,'Enter matrix (row by row):',0dh,'$';приглашение для ввода элементов
sSource db 0ah,0ah,'Source matrix:',0dh,0ah,'$'
sResult db 0ah,'Result matrix:',0dh,0ah,'$'
sPress db 0ah,'Press any key for exit$'
sError db 0ah,0ah,'Capacity may be >=1 and <=4',0dh,0ah,0ah,'$'
P dw 0  ;для проверки массива
 .data?
;буфер для ввода числовой строки (для функции 0ah)
sNum db ?  ;максимальный размер буфера
sCount db ?  ;реальный размер строки
sBuf db 80 dup (?) ;сама строка

N dw ?  ;размерность матрицы
array_a label word  ;матрица (разместим в конце)
array_b label word


 .code
 .startup
gd_rep:
 call GetDim ;введем размерность
 jnz repeat 
 jmp gd_rep
repeat:
 call GetMatrix ;введем матрицу
 call GetMatrix
 
continue:
 lea dx, sSource ;выведем исходную матрицу
 call PrintMatrix
 lea dx, sSource ;выведем исходную матрицу
 call PrintMatrix
 lea dx, sPress ;Press any key
 mov ah, 9
 int 21h

 mov ah, 0  ;ждем "any key"
 int 16h

 mov ax, 4c00h ;выход
 int 21h

PrintMatrix proc  ;вывод матрицы NxN
 mov ah, 9
 int 21h  ;вывод заголовока из dx
 mov P,0
 cmp P,0
 je mas_ar
 jmp mas_br
mas_ar:
 lea si, array_a ;адрес массива
 mov cx, N  ;число строк
 jmp PrintRowLoop
mas_br:
 lea si, array_b ;адрес массива
 mov cx, N  ;число строк
PrintRowLoop:   ;вывод строк
 push cx  ;сохраним счетчик строк
 mov cx, N  ;чисо столбцов
PrintColLoop:   ;вывод одной строки
 lodsw   ;очередное значение
 call PrintNum ;вывод числовой строки
 mov dl, 9  ;разделим табуляцией
 int 21h  ;ah = 2
 loop PrintColLoop
 mov dl, 0dh  ;переход на новую строку
 int 21h
 mov dl, 0ah
 int 21h
 pop cx  ;восстановим счетчик строк
 loop PrintRowLoop
 ret
PrintMatrix endp

PrintNum proc  ;вывод беззнакового числа из ax
 push cx  ;сохраним счетчик колонок
 mov bx, 10  ;будем делить на 10
 xor cx, cx  ;счетчик цифр
DivLoop:
 xor dx, dx  ;готовимся к делению dx:ax / bx
 div bx  ;ax - частное, dx - остаток=очередной младшей цифре
 push dx  ;сохраним цифру в стеке
 inc cx  ;посчитаем
 test ax, ax  ;продолжим, пока не 0
 jnz DivLoop
 mov ah, 2  ;функция вывода
PrintLoop:   ;будем выводить в обратном порядке, начиная со старшей шифры
 pop dx  ;восстановим очередной разряд
 or dl, '0'  ;превратим в символ
 int 21h  ;выведем
 loop PrintLoop
 pop cx  ;восстановим счетчик колонок матрицы
 ret
PrintNum endp
GetDim proc
sw:
 lea dx, sGet
 mov ah, 9
 int 21h  ;приглашение на ввод размерности матрицы

 mov sNum, 80 ;задаем максимальное значение
 lea dx, sNum
 mov ah, 0ah
 int 21h  ;водим строку

 lea si, sBuf ;строка
 call stoi  ;преобразовываем в число
 cmp ax,2  ;проверим на корректность
 jb GD_err
 cmp ax,4  ;ждем 2 <= N <= 4
 ja GD_err
 mov N, ax  ;сохраняем размерность
 jmp GD_ok
GD_err:
 lea dx, sError ;сообщение об ошибке
 mov ah, 9
 int 21h
 jmp sw
 ;or ax, 1  ;FZ == 0 -> ошибка размерности
GD_ok:
 ret
GetDim endp
GetMatrix proc  ;ввод матрицы
 cmp P,0
 je mas_a
 jmp mas_b
mas_a:
 mov P,1
 lea dx, sMatrix
 mov ah, 9
 int 21h  ;приглашение на ввод элементов матрицы
 
 lea di, array_a ;адрес массива

 mov ax, N  ;адрес за массивом (для контроля конца)
 mul N
 shl ax, 1
 add ax, offset array_a
 mov bp, ax  ;сохраним в bp
 jmp GM_ask
mas_b:
 lea dx, sMatrix
 mov ah, 9
 int 21h  ;приглашение на ввод элементов матрицы
 
 lea di, array_b ;адрес массива

 mov ax, N  ;адрес за массивом (для контроля конца)
 mul N
 shl ax, 1
 add ax, offset array_b
 mov bp, ax  ;сохраним в bp
GM_ask:
 mov ah, 2
 mov dl, 0ah
 int 21h  ;переход на новую строку

 mov sNum, 80
 lea dx, sNum
 mov ah, 0ah
 int 21h
 lea si, sBuf ;строка с числами, разделенная разделителями

GM_next:
 cmp di, bp  ;массив заполнен?
 je GM_ok

 call stoi  ;[si] в число
 jcxz GM_ask  ;дошли до конца строки?
 stosw   ;сохраняем
 jmp GM_next  ;на следующее число в строке
GM_err:
 or ax, 1  ;FZ == 0 -> ошибка размерности
GM_ok:
 ret   ;FZ == 0 -> все ок
GetMatrix endp

stoi proc   ;преобразование строки [si] в число AX
 xor bx, bx  ;здесь будем стоить число
 xor cx, cx  ;счетчик разрядов
stoi_next:
 lodsb   ;очередной символ
 cmp al, 0dh  ;конец стоки?
 je stoi_eol
 cmp al, '0'
 jb stoi_sep ;любая нецифра - разделитель
 cmp al, '9'
 ja stoi_sep
 push ax  ;сохраним новый разряд
 mov ax, 10
 mul bx  ;умножим старшие на 10
 pop dx  ;новый
 and dx, 0fh  ;'0'-'9' -> 0-9
 add ax, dx  ;добавляем новый разряд
 mov bx, ax  ;сохраняем
 inc cx  ;считаем
 jmp stoi_next ;продолжаем
stoi_sep:   ;встретили разделитель
 jcxz stoi_next ;были только разделители - на продолжение
    ; иначе - конец числа и выходим
stoi_eol:   ; если числа нет и встретили 0dh - конец строки
 mov ax, bx  ;число возвращаем в ax
 dec si  ;шаг назад, чтобы легче было проанализировать 0dh
 ret
stoi endp

 end

Дата отправки: 20.09.2011, 07:34
Вопрос задал: Миша Врумин (Посетитель)
Всего ответов: 1
Страница онлайн-консультации »


Консультирует Лысков Игорь Витальевич (Старший модератор):

Здравствуйте, Миша Врумин!
Можно делать по-разному. Например, так:

Код :
.model tiny

 .data
sGet db 'Enter matrix capacity: $'  ;приглашение для ввода размерности
sMatrixA db 0ah,'Enter matrix A (row by row):',0dh,'$';приглашение для ввода элементов A
sMatrixB db 0ah,'Enter matrix B (row by row):',0dh,'$';приглашение для ввода элементов B
sSourceA db 0ah,0ah,'Source matrix A:',0dh,0ah,'$'
sSourceB db 0ah,0ah,'Source matrix B:',0dh,0ah,'$'
sResult db 0ah,'Result matrix:',0dh,0ah,'$'
sPress db 0ah,'Press any key for exit$'
sError db 0ah,0ah,'Capacity may be >=1 and <=4',0dh,0ah,0ah,'$'
 .data?
;буфер для ввода числовой строки (для функции 0ah)
sNum db ?  ;максимальный размер буфера
sCount db ?  ;реальный размер строки
sBuf db 80 dup (?) ;сама строка

N dw ?  ;размерность матрицы
array_a label word  ;матрица (разместим в конце)
array_b equ array_a+4*4*2


 .code
 .startup
gd_rep:
 call GetDim ;введем размерность
 jz gd_rep

 lea dx, sMatrixA
 lea di, array_a ;адрес массива
 call GetMatrix ;введем матрицу
 lea dx, sMatrixB
 lea di, array_b ;адрес массива
 call GetMatrix
 
continue:
 lea dx, sSourceA ;выведем исходную матрицу A
 lea si, array_a ;адрес массива
 call PrintMatrix
 lea dx, sSourceB ;выведем исходную матрицуB
 lea si, array_b ;адрес массива
 call PrintMatrix

 lea dx, sPress ;Press any key
 mov ah, 9
 int 21h

 mov ah, 0  ;ждем "any key"
 int 16h

 mov ax, 4c00h ;выход
 int 21h

PrintMatrix proc  ;вывод матрицы NxN
 mov ah, 9
 int 21h  ;вывод заголовока из dx
 mov cx, N  ;число строк
PrintRowLoop:   ;вывод строк
 push cx  ;сохраним счетчик строк
 mov cx, N  ;чисо столбцов
PrintColLoop:   ;вывод одной строки
 lodsw   ;очередное значение
 call PrintNum ;вывод числовой строки
 mov dl, 9  ;разделим табуляцией
 int 21h  ;ah = 2
 loop PrintColLoop
 mov dl, 0dh  ;переход на новую строку
 int 21h
 mov dl, 0ah
 int 21h
 pop cx  ;восстановим счетчик строк
 loop PrintRowLoop
 ret
PrintMatrix endp

PrintNum proc  ;вывод беззнакового числа из ax
 push cx  ;сохраним счетчик колонок
 mov bx, 10  ;будем делить на 10
 xor cx, cx  ;счетчик цифр
DivLoop:
 xor dx, dx  ;готовимся к делению dx:ax / bx
 div bx  ;ax - частное, dx - остаток=очередной младшей цифре
 push dx  ;сохраним цифру в стеке
 inc cx  ;посчитаем
 test ax, ax  ;продолжим, пока не 0
 jnz DivLoop
 mov ah, 2  ;функция вывода
PrintLoop:   ;будем выводить в обратном порядке, начиная со старшей шифры
 pop dx  ;восстановим очередной разряд
 or dl, '0'  ;превратим в символ
 int 21h  ;выведем
 loop PrintLoop
 pop cx  ;восстановим счетчик колонок матрицы
 ret
PrintNum endp

GetDim proc
sw:
 lea dx, sGet
 mov ah, 9
 int 21h  ;приглашение на ввод размерности матрицы

 mov sNum, 80 ;задаем максимальное значение
 lea dx, sNum
 mov ah, 0ah
 int 21h  ;водим строку

 lea si, sBuf ;строка
 call stoi  ;преобразовываем в число
 cmp ax,2  ;проверим на корректность
 jb GD_err
 cmp ax,4  ;ждем 2 <= N <= 4
 ja GD_err
 mov N, ax  ;сохраняем размерность
 jmp GD_ok
GD_err:
 lea dx, sError ;сообщение об ошибке
 mov ah, 9
 int 21h
 jmp sw
 ;or ax, 1  ;FZ == 0 -> ошибка размерности
GD_ok:
 ret
GetDim endp
GetMatrix proc  ;ввод матрицы
 mov ah, 9
 int 21h  ;приглашение на ввод элементов матрицы
 
 mov ax, N  ;адрес за массивом (для контроля конца)
 mul N
 shl ax, 1
 add ax, di
 mov bp, ax  ;сохраним в bp
GM_ask:
 mov ah, 2
 mov dl, 0ah
 int 21h  ;переход на новую строку

 mov sNum, 80
 lea dx, sNum
 mov ah, 0ah
 int 21h
 lea si, sBuf ;строка с числами, разделенная разделителями

GM_next:
 cmp di, bp  ;массив заполнен?
 je GM_ok

 call stoi  ;[si] в число
 jcxz GM_ask  ;дошли до конца строки?
 stosw   ;сохраняем
 jmp GM_next  ;на следующее число в строке
GM_err:
 or ax, 1  ;FZ == 0 -> ошибка размерности
GM_ok:
 ret   ;FZ == 0 -> все ок
GetMatrix endp

stoi proc   ;преобразование строки [si] в число AX
 xor bx, bx  ;здесь будем стоить число
 xor cx, cx  ;счетчик разрядов
stoi_next:
 lodsb   ;очередной символ
 cmp al, 0dh  ;конец стоки?
 je stoi_eol
 cmp al, '0'
 jb stoi_sep ;любая нецифра - разделитель
 cmp al, '9'
 ja stoi_sep
 push ax  ;сохраним новый разряд
 mov ax, 10
 mul bx  ;умножим старшие на 10
 pop dx  ;новый
 and dx, 0fh  ;'0'-'9' -> 0-9
 add ax, dx  ;добавляем новый разряд
 mov bx, ax  ;сохраняем
 inc cx  ;считаем
 jmp stoi_next ;продолжаем
stoi_sep:   ;встретили разделитель
 jcxz stoi_next ;были только разделители - на продолжение
    ; иначе - конец числа и выходим
stoi_eol:   ; если числа нет и встретили 0dh - конец строки
 mov ax, bx  ;число возвращаем в ax
 dec si  ;шаг назад, чтобы легче было проанализировать 0dh
 ret
stoi endp

 end

Консультировал: Лысков Игорь Витальевич (Старший модератор)
Дата отправки: 20.09.2011, 11:45
Рейтинг ответа:

НЕ одобряю 0 одобряю!


Оценить выпуск | Задать вопрос экспертам

главная страница  |  стать участником  |  получить консультацию
техническая поддержка  |  восстановить логин/пароль

Дорогой читатель!
Команда портала RFPRO.RU благодарит Вас за то, что Вы пользуетесь нашими услугами. Вы только что прочли очередной выпуск рассылки. Мы старались. Пожалуйста, оцените его. Если совет помог Вам, если Вам понравился ответ, Вы можете поблагодарить автора - для этого в каждом ответе есть специальные ссылки. Вы можете оставить отзыв о работе портале. Нам очень важно знать Ваше мнение. Вы можете поближе познакомиться с жизнью портала, посетив наш форум, почитав журнал, который издают наши эксперты. Если у Вас есть желание помочь людям, поделиться своими знаниями, Вы можете зарегистрироваться экспертом. Заходите - у нас интересно!
МЫ РАБОТАЕМ ДЛЯ ВАС!



В избранное