Консультация № 184059
20.09.2011, 07:34
0.00 руб.
20.09.2011, 11:49
0 9 1
Уважаемые эксперты! Пожалуйста, ответьте на вопрос:
Задание:
Разделить элементы массива A на соответствующие элементы массива B и записать результат в массив B.
Размерность вводится пользователем, и элементы также.
Ошибка в том, что не могу понять как сделать разно-адресные массивы (чтобы запоминались элементы и первого массива и второго)
Пишу в Tasm, под 32 бит.
Код
[code h=207]
.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
[/code]

Обсуждение

давно
Старший Модератор
31795
6196
20.09.2011, 11:31
общий
1)
Код:
gd_rep:
call GetDim ;введем размерность
jnz repeat;ZF=0
jmp gd_rep;ZF=1 => jz gd_rep
repeat:

Таких участков несколько.

2)
Какой смысл от такой проверки?
Код:
	mov P,0
в эту точку перехода нет
cmp P,0
je mas_ar
jmp mas_br
mas_ar:


3)
Вы не используете 32-ти битные регистры, почему бы Вам не скачать Turbo Assembler 4.1 16-ть бит.

4)
Ввод чисел нужно с помощью строк делать, или можно по другому?

Об авторе:
Мне безразлично, что Вы думаете о обо мне, но я рад за Вас - Вы начали думать.

давно
Посетитель
7438
7205
20.09.2011, 11:45
общий
это ответ
Здравствуйте, Миша Врумин!
Можно делать по-разному. Например, так:

[code h=207].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[/code]
Об авторе:
"Если вы заметили, что вы на стороне большинства, —
это верный признак того, что пора меняться." Марк Твен
давно
Посетитель
7438
7205
20.09.2011, 11:50
общий
Кстати, удивительно знакомый код ...
Об авторе:
"Если вы заметили, что вы на стороне большинства, —
это верный признак того, что пора меняться." Марк Твен
давно
Посетитель
7438
7205
20.09.2011, 11:53
общий
20.09.2011, 11:54
Адресаты:
2)
Какой смысл от такой проверки?
Код:
	mov P,0
в эту точку перехода нет
cmp P,0
je mas_ar
jmp mas_br
mas_ar:


В этом как раз и смысл вопроса...
У человека не получается ввести два массива.
Это была попытка регулировать при помощи переменной Р...
Об авторе:
"Если вы заметили, что вы на стороне большинства, —
это верный признак того, что пора меняться." Марк Твен
Неизвестный
20.09.2011, 18:38
общий
мм все возможно, код был вырван кусками из разных всех сайтов и собран в один прекрасный.
Возникла проблема теперь связанная скорее с ПО
При создание .com файла вылетает ошибка Debug into switch ignored for .COM files
в код добавил лишь пару строчек да и то не значительных, такого результат они не могли дать.
Есть у кого какие предположения?
давно
Старший Модератор
31795
6196
20.09.2011, 19:19
общий
Какие строчки добавили, какими командами компилировали?


Скорее всего попытались компилировать с отладочной информацией.
Об авторе:
Мне безразлично, что Вы думаете о обо мне, но я рад за Вас - Вы начали думать.

Неизвестный
20.09.2011, 20:53
общий
так строчки добавил
divm:
lea dx,sResult
mov ah,9
int 21h
lea si,array_b
call PrintMatrix

а компилировал
"C:\Tasm\Tasm.exe C:\Tasm\who\lab4.asm"
" C:\Tasm\TLINK.exe C:\Tasm\who\lab4.obj /t /v( потом убрал но ошибка осталась)"

давно
Посетитель
7438
7205
21.09.2011, 01:11
общий
21.09.2011, 01:46
Во-первых, сообщение "Debug into switch ignored for .COM files" - это не ошибка, а предупреждение (warning)
Во-вторых, сообщение означает, что ключ, заданный для включения отладочной информации в COM-файл, игнорируется. Речь идет о ключе /v, который Вы задали. Все правильно! Он для COM-файла не имеет смысла. Ничего страшного не произошло. Tlink просто проигнорировал параметр /v, который лишний. Уберите его, пропадет и предупреждение.
Об авторе:
"Если вы заметили, что вы на стороне большинства, —
это верный признак того, что пора меняться." Марк Твен
давно
Посетитель
7438
7205
22.09.2011, 00:05
общий
Место под массивы, заданное:
Код:
array_a	label	word		;матрица (разместим в конце)
array_b equ array_a+4*4*2
можно выделить по-другому:
Код:
array_a	dw	4*4 dup(?)
array_b dw 4*4 dup(?)
Об авторе:
"Если вы заметили, что вы на стороне большинства, —
это верный признак того, что пора меняться." Марк Твен
Форма ответа