01.10.2011, 22:49
общий
это ответ
Здравствуйте, Дмитрий!
Вот Вам такой вариант.
Исходные числа рассматриваются, как обычные двоичные числа.
Т.к. они по условию двуразрядные, то для хранения достаточно одного байта.
Для квадратов же необходимо два байта-слово.
[code h=207]
.model small
.stack 100h
Color equ 07h ;цвет выводимых данных
.data
sNumbers db 'Numbers: ',0
sSquares db 'Squares: ',0
sPress db 'Press any key',0
Numbers db 21, 34, 99, 10, 15, 16 ;примерный массив чисел
lenNumbers equ $-Numbers ;длина массива
Square dw lenNumbers dup (?) ;массив слов квадратов чисел
sNum db 8 dup (?) ;буфер для преобразования числа в строку
.code
main proc
mov ax, @DATA ;настроим сегментные регистры
mov ds, ax ;DS - сегмент данных
mov ax, 0b800h
mov es, ax ;ES - сегмент видеобуфера
mov ah, 3 ;необходимо, чтобы под ХР правильно
int 10h ;работала прямая запись в видеопамять
call CalcSquare ;посчитаем квадраты
call PrintResult ;выведем результат работы
lea si, sPress ;Press any key
mov di, 3*80*2 ;в начале четвертой строки
call print ;выводим
mov ah, 2 ;установим курсор
mov dx, 0400h ;в начале пятой строки
mov bh, 0
int 10h
mov ah, 0 ;ждем "any key"
int 16h ;чтобы сразу не убегало с экрана
mov ax, 4c00h
int 21h
main endp
CalcSquare proc ;расчет квадратов
lea si, Numbers ;адрес массива однобайтных чисел
lea di, Square ;адрес массива двубайтных чисел
mov cx, lenNumbers ;количество чисел
CalcLoop: ;цикл по всем числам
lodsb ;читаем al=ds:[si],si=si+1
mul al ;ax=al*al
mov [di], ax ;сохраняем ds:[di]=ax
inc di ;увеличиваем на 2 индекс квадратов
inc di ;stosw не годится, т.к. es - видеобуфер!
loop CalcLoop
ret
CalcSquare endp
PrintNum proc ;вывод числа на экран из ax,
;начиная с позиции es:[di]
;после выхода di указывает на
;следующую позицию в строке
push si ;сохраним индекс в массиве чисел
push di ;сохраним индекс в видеобуфере
lea di, sNum ;адрес временного буфера
mov si, di ;запомним для вывода на экран
call itoa ;преобразуем ax в строку ds:[di]
pop di ;восстановим адрес на экране
call print ;выводим ds:[si] на экран es:[di]
mov al, ' ' ;отделим пробелом, ah = Color
stosw
pop si ;восстановим индекс в массиве чисел
ret
PrintNum endp
PrintResult proc ;вывод результата работы
lea si, sNumbers ;адрес строки 'Numbers: ',0
xor di, di ;с начала первой строки
call print ;выводим
lea si, Numbers ;адрес массива однобайтных чисел
mov cx, lenNumbers ;число чисел
PrNumLoop:
xor ax, ax ;обнулим ah, чтобы получилось слово
lodsb ;ax = слову, равному байту
call PrintNum ;выводим ax за выведенной ранее строкой
loop PrNumLoop ;по всем
;выведем квадраты
lea si, sSquares ;адрес строки 'Squares: ',0
mov di, 1*80*2 ;с начала второй строки
call print ;выводим
lea si, Square ;адрес массива квадратов
mov cx, lenNumbers ;количество
PrSquareLoop:
lodsw ;читаем слово
call PrintNum ;выводим
loop PrSquareLoop ;по всем
ret
PrintResult endp
print proc ;вывод на экран строки ds:[si]
;по адресу es:[di]
mov ah, Color ;атрибут (цвет)
printLoop:
lodsb ;очередной
cmp al, 0 ;конец строки?
je printRet
stosw ;выводим
jmp printLoop
printRet:
ret
print endp
itoa proc ;преобразование числа из ax в строку
;по адресу ds:[di]
push cx ;сохраним счетчик чисел
xor cx, cx ;счетчик цифр
mov bx, 10 ;будем делить на 10
div_loop:
xor dx, dx ;сбросим предыдущий остаток
div bx ;делим dx:ax/bx
push dx ;сохраним остаток dx в стеке
inc cx ;посчитаем
test ax, ax ;делим, пока ax не 0
jnz div_loop
pr_loop: ;цикл вывода
pop ax ;восстановим из стека очередную цифру
or al, '0' ;сделаем из числа символ
mov [di], al ;запишем по адресу [di++]
inc di
loop pr_loop
mov byte ptr [di], 0;закроем строку нулем
pop cx ;восстановим счетчик чисел
ret
itoa endp
end main
[/code]
Об авторе:
"Если вы заметили, что вы на стороне большинства, —
это верный признак того, что пора меняться." Марк Твен