Консультация № 184122
30.09.2011, 19:53
65.51 руб.
0 11 2
Уважаемые эксперты! Пожалуйста, ответьте на вопрос:помогите написать программу.
Дан массив двухразрядных десятичных чисел.Создать второй массив, содержащий квадраты этих чисел;результат в символьной форме переслать в видео буфер.Ассемблер-Tasm.exe Исполняемый файл в формате EXE.
Очень надеюсь, что Вы мне поможете.

Обсуждение

давно
Посетитель
7438
7205
30.09.2011, 20:25
общий
Конечно, поможем...
Только уточните, пожалуйста:
1) Разрядность массива? (Или без разницы)
2) Разрядность задаем в программе или вводим?
3) Массив задаем в программе или вводим?
4) "переслать в видеобуфер" - имеется в виду прямая запись в видеопамять?
Об авторе:
"Если вы заметили, что вы на стороне большинства, —
это верный признак того, что пора меняться." Марк Твен
давно
Старший Модератор
31795
6196
30.09.2011, 20:38
общий

1)длина массива? а можно для всех 10:99?
2)можно прямо в видеобуфер закачивать результат, без создания второго массива?(в этом случае можно организовать форматированный вывод информации).
Об авторе:
Мне безразлично, что Вы думаете о обо мне, но я рад за Вас - Вы начали думать.

Неизвестный
30.09.2011, 20:54
общий
Адресаты:
1)без разницы
2)в программе
3)в программе
4)да в видеопамять
давно
Посетитель
7438
7205
30.09.2011, 22:50
общий
30.09.2011, 22:51
Еще вопрос:
"двухразрядные десятичные числа" - имеется в виду число занимает байт в формате BCD
(например, число 12h = 1210)?
В квадрате число тогда будет занимать два байта (122 = 144 = 0144h).
Впрочем, в квадрате по-любому будет два байта...

Или используем обычные двоичные числа? (те же 1210 = 0сh )
Об авторе:
"Если вы заметили, что вы на стороне большинства, —
это верный признак того, что пора меняться." Марк Твен
Неизвестный
01.10.2011, 14:49
общий
Адресаты:
обычные двоично-десятичные числа Например: одиннадцать,двенадцать и т.д. и соответственно их квадраты
Неизвестный
01.10.2011, 14:50
общий
и первый массив однобайтный,а второй двух байтный
давно
Старший Модератор
31795
6196
01.10.2011, 20:37
общий
Цитата: 381678
обычные двоично-десятичные числа

Умножение можно производить только двоичных чисел(команда mul), в других случаях используется коррекция или длинная арифметика..
Двоично-десятичные числа(BCD), это несколько другая область представления числа. Каждая десятичная цифра записывается с помощью 4-х бит, т.е. в одном байте содержится две BCD цифры.


Отсюда вопрос: какую тему Вы сейчас проходите?
Желательно бы выложить Вашу методичку, т.к. (не обижайтесь) можно настолько оптимизировать программу, что человек не имеющий опыта работы с ассемблером, в том числе иногда и сам преподаватель,получает- ставит двоийки, т.к. не смог разобратся в предоставленной программе. Даже если она выдает правильные результаты.
Об авторе:
Мне безразлично, что Вы думаете о обо мне, но я рад за Вас - Вы начали думать.

Неизвестный
01.10.2011, 21:04
общий
01.10.2011, 21:05
Цитата: Зенченко Константин Николаевич
обычные двоично-десятичные числа

Это опечатка. В задание написано "Дан массив двухразрядных десятичных чисел", тоесть числа от 10 до 99 в десятичной системе счисления.
давно
Посетитель
7438
7205
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]
Об авторе:
"Если вы заметили, что вы на стороне большинства, —
это верный признак того, что пора меняться." Марк Твен
давно
Старший Модератор
31795
6196
01.10.2011, 23:04
общий
это ответ
Здравствуйте, Дмитрий!

Ещё один вариант решения Вашей задачи.
Выводится все квадраты чисел от 10 до 99, с форматированием вывода.
100% tasm(2.00+), masm код просто не скомпилирует.
Удачи!

Приложение:
model small,pascal
.stack 100h
.code
bit7 equ 00000000b;мерцание
; 0ххх0000;границы значений
bit6_4 equ 01110000b;цвет фона - серый
; 0000хххх;границы значений
bit3_0 equ 00001111b;цвет символа - белый
atrrib equ bit7+bit6_4+bit3_0;аттрибут символа
begin:
;устанавливаеи видео режим
mov ax,3
int 10h
;настраиваем сегментные регистры
mov ax,@data
mov ds,ax
mov es,ax
;
;настраиваемся на массив
mov cx,szArray
lea si,dbArray
lea di,dwArray
cld
;
;цикл фрмирования второго массива
mainLoop: xor ax,ax;
lodsb;
xor dx,dx
mul ax;квадрат получаем и записываем
stosw
loop mainLoop
;
;настраиваемся для вывода в видео буфер
lea si,dwArray;адрес результатат
xor di,di;адрес видеобуфера
mov ax,0b800h;адрес сегмента видеобуфера
mov es,ax;
mov cx,szArray;размер массива
;
;цикл вывода значения и результата
MoveLoop: lodsw;загружаем число
call showData,cx,ax;выводим значение и квадрат
loop MoveLoop
;
;любая клавиша и выход в ДОС
xor ax,ax
int 16h
mov ax,4c00h
int 21h
;
;подпрограмма вывода значения числа и квадрата
proc showData, dwNumber:word, dwResult:word
push cx
;считаем число и выводим
mov ax,szArray+10
sub ax,dwNumber
call showNumber,ax,11;11-параметр форматирования
;получаем результат и выводим
mov ax,dwResult
call showNumber,ax,5;5_параметр форматирования
;востанавливаем сохраненные регистры
pop cx
ret
endp showData
;
;подпрограмма вывода одного числа с форматированием по длине
proc showNumber, dwNumber:word, dwFormat:word
;загружаем число и настраиваемся для работы в 10-й систме
mov ax,dwNumber
xor cx,cx
mov bx,10
;цикл получения остатка деления на 10
@@01: xor dx,dx
div bx
;всё сохраняется в стеке и считается количество сохранений
push dx
inc cx
or ax,ax
jnz @@01
;
;форматиреум выводимое число
mov ax,-10h
@@02: inc cx
push ax
cmp cx,dwFormat
jb @@02
;
;записываем в видеобуфер выводимую информацию
@@03: pop ax
add ax,30h
mov ah,atrrib
stosw
loop @@03
ret
endp showNumber
.data
;
;компилятор формирует исходный массив
currentNumber = 10;
dbArray label byte
rept (100-10)
db currentNumber
currentNumber = currentNumber + 1
endm
szArray equ $ - dbArray
;
;это метка массива результата
dwArray label word
end begin
Об авторе:
Мне безразлично, что Вы думаете о обо мне, но я рад за Вас - Вы начали думать.

давно
Старший Модератор
31795
6196
01.10.2011, 23:18
общий
01.10.2011, 23:19
[code h=200]Turbo Assembler Version 2.0 10/01/11 21:55:52 Page 1
q184122.ASM



1 0000 model small,pascal
2 0000 .stack 100h
3 0000 .code
4 = 0000 bit7 equ 00000000b;мерцание
5 ; 0ххх0000;границы значений
6 = 0070 bit6_4 equ 01110000b;цвет фона - серый
7 ; 0000хххх;границы значений
8 = 000F bit3_0 equ 00001111b;цвет символа - белый
9 = 007F atrrib equ bit7+bit6_4+bit3_0;аттрибут символа
10 0000 begin:
11 ;устанавливаеи видео режим
12 0000 B8 0003 mov ax,3
13 0003 CD 10 int 10h
14 ;настраиваем сегментные регистры
15 0005 B8 0000s mov ax,@data
16 0008 8E D8 mov ds,ax
17 000A 8E C0 mov es,ax
18 ;
19 ;настраиваемся на массив
20 000C B9 005A 90 mov cx,szArray
21 0010 BE 0000r lea si,dbArray
22 0013 BF 005Ar lea di,dwArray
23 0016 FC cld
24 ;
25 ;цикл фрмирования второго массива
26 0017 33 C0 mainLoop: xor ax,ax;
27 0019 AC lodsb;
28 001A 33 D2 xor dx,dx
29 001C F7 E0 mul ax;квадрат получаем и записываем
30 001E AB stosw
31 001F E2 F6 loop mainLoop
32 ;
33 ;настраиваемся для вывода в видео буфер
34 0021 BE 005Ar lea si,dwArray;адрес результатат
35 0024 33 FF xor di,di;адрес видеобуфера
36 0026 B8 B800 mov ax,0b800h;адрес сегмента видеобуфера
37 0029 8E C0 mov es,ax;
38 002B B9 005A 90 mov cx,szArray;размер массива
39 ;
40 ;цикл вывода значения и результата
41 002F AD MoveLoop: lodsw;загружаем число
42 call showData,cx,ax;выводим значение и квадрат
1 43 0030 51 PUSH CX
1 44 0031 50 PUSH AX
1 45 0032 E8 000B CALL SHOWDATA
46 0035 E2 F8 loop MoveLoop
47 ;
48 ;любая клавиша и выход в ДОС
49 0037 33 C0 xor ax,ax
50 0039 CD 16 int 16h
51 003B B8 4C00 mov ax,4c00h
52 003E CD 21 int 21h
53 ;
54 ;подпрограмма вывода значения числа и квадрата
55 0040 proc showData, dwNumber:word, dwResult:word
1 56 0040 55 PUSH BP
1 57 0041 8B EC MOV BP,SP
Turbo Assembler Version 2.0 10/01/11 21:55:52 Page 2
q184122.ASM



1 58 0043 51 push cx
59 ;считаем число и выводим
60 0044 B8 0064 mov ax,szArray+10
61 0047 2B 46 06 sub ax,dwNumber
62 call showNumber,ax,11;11-параметр форматирования
1 63 004A 50 PUSH AX
1 64 004B 50 55 8B EC C7 46 02+ PUSH 11
65 000B 5D
1 66 0055 E8 0016 CALL SHOWNUMBER
67 ;получаем результат и выводим
68 0058 8B 46 04 mov ax,dwResult
69 call showNumber,ax,5;5_параметр форматирования
1 70 005B 50 PUSH AX
1 71 005C 50 55 8B EC C7 46 02+ PUSH 5
72 0005 5D
1 73 0066 E8 0005 CALL SHOWNUMBER
74 ;востанавливаем сохраненные регистры
75 0069 59 pop cx
1 76 006A 5D POP BP
1 77 006B C2 0004 RET 0004h
78 006E endp showData
79 ;
80 ;подпрограмма вывода одного числа с форматированием по длине
81 006E proc showNumber, dwNumber:word, dwFormat:word
82 ;загружаем число и настраиваемся для работы в 10-й систме
1 83 006E 55 PUSH BP
1 84 006F 8B EC MOV BP,SP
1 85 0071 8B 46 06 mov ax,dwNumber
86 0074 33 C9 xor cx,cx
87 0076 BB 000A mov bx,10
88 ;цикл получения остатка деления на 10
89 0079 33 D2 @@01: xor dx,dx
90 007B F7 F3 div bx
91 ;всё сохраняется в стеке и считается количество сохранений
92 007D 52 push dx
93 007E 41 inc cx
94 007F 0B C0 or ax,ax
95 0081 75 F6 jnz @@01
96 ;
97 ;форматиреум выводимое число
98 0083 B8 FFF0 mov ax,-10h
99 0086 41 @@02: inc cx
100 0087 50 push ax
101 0088 3B 4E 04 cmp cx,dwFormat
102 008B 72 F9 jb @@02
103 ;
104 ;записываем в видеобуфер выводимую информацию
105 008D 58 @@03: pop ax
106 008E 05 0030 add ax,30h
107 0091 B4 7F mov ah,atrrib
108 0093 AB stosw
109 0094 E2 F7 loop @@03
1 110 0096 5D POP BP
1 111 0097 C2 0004 RET 0004h
112 009A endp showNumber
113 009A .data
114 ;
Turbo Assembler Version 2.0 10/01/11 21:55:52 Page 3
q184122.ASM



115 ;компилятор формирует исходный массив
116 = 000A currentNumber = 10;
117 0000 dbArray label byte
118 rept (100-10)
119 db currentNumber
120 currentNumber = currentNumber + 1
121 endm
1 122 0000 0A db currentNumber
1 123 0001 0B db currentNumber
1 124 0002 0C db currentNumber
1 125 0003 0D db currentNumber
1 126 0004 0E db currentNumber
1 127 0005 0F db currentNumber
1 128 0006 10 db currentNumber
1 129 0007 11 db currentNumber
1 130 0008 12 db currentNumber
1 131 0009 13 db currentNumber
1 132 000A 14 db currentNumber
1 133 000B 15 db currentNumber
1 134 000C 16 db currentNumber
1 135 000D 17 db currentNumber
1 136 000E 18 db currentNumber
1 137 000F 19 db currentNumber
1 138 0010 1A db currentNumber
1 139 0011 1B db currentNumber
1 140 0012 1C db currentNumber
1 141 0013 1D db currentNumber
1 142 0014 1E db currentNumber
1 143 0015 1F db currentNumber
1 144 0016 20 db currentNumber
1 145 0017 21 db currentNumber
1 146 0018 22 db currentNumber
1 147 0019 23 db currentNumber
1 148 001A 24 db currentNumber
1 149 001B 25 db currentNumber
1 150 001C 26 db currentNumber
1 151 001D 27 db currentNumber
1 152 001E 28 db currentNumber
1 153 001F 29 db currentNumber
1 154 0020 2A db currentNumber
1 155 0021 2B db currentNumber
1 156 0022 2C db currentNumber
1 157 0023 2D db currentNumber
1 158 0024 2E db currentNumber
1 159 0025 2F db currentNumber
1 160 0026 30 db currentNumber
1 161 0027 31 db currentNumber
1 162 0028 32 db currentNumber
1 163 0029 33 db currentNumber
1 164 002A 34 db currentNumber
1 165 002B 35 db currentNumber
1 166 002C 36 db currentNumber
1 167 002D 37 db currentNumber
1 168 002E 38 db currentNumber
1 169 002F 39 db currentNumber
1 170 0030 3A db currentNumber
1 171 0031 3B db currentNumber
Turbo Assembler Version 2.0 10/01/11 21:55:52 Page 4
q184122.ASM



1 172 0032 3C db currentNumber
1 173 0033 3D db currentNumber
1 174 0034 3E db currentNumber
1 175 0035 3F db currentNumber
1 176 0036 40 db currentNumber
1 177 0037 41 db currentNumber
1 178 0038 42 db currentNumber
1 179 0039 43 db currentNumber
1 180 003A 44 db currentNumber
1 181 003B 45 db currentNumber
1 182 003C 46 db currentNumber
1 183 003D 47 db currentNumber
1 184 003E 48 db currentNumber
1 185 003F 49 db currentNumber
1 186 0040 4A db currentNumber
1 187 0041 4B db currentNumber
1 188 0042 4C db currentNumber
1 189 0043 4D db currentNumber
1 190 0044 4E db currentNumber
1 191 0045 4F db currentNumber
1 192 0046 50 db currentNumber
1 193 0047 51 db currentNumber
1 194 0048 52 db currentNumber
1 195 0049 53 db currentNumber
1 196 004A 54 db currentNumber
1 197 004B 55 db currentNumber
1 198 004C 56 db currentNumber
1 199 004D 57 db currentNumber
1 200 004E 58 db currentNumber
1 201 004F 59 db currentNumber
1 202 0050 5A db currentNumber
1 203 0051 5B db currentNumber
1 204 0052 5C db currentNumber
1 205 0053 5D db currentNumber
1 206 0054 5E db currentNumber
1 207 0055 5F db currentNumber
1 208 0056 60 db currentNumber
1 209 0057 61 db currentNumber
1 210 0058 62 db currentNumber
1 211 0059 63 db currentNumber
212 = 005A szArray equ $ - dbArray
213 ;
214 ;это метка массива результата
215 005A dwArray label word
216 end begin
Turbo Assembler Version 2.0 10/01/11 21:55:52 Page 5
Symbol Table




Symbol Name Type Value

??DATE Text "10/01/11"
??FILENAME Text "q184122 "
??TIME Text "21:55:52"
??VERSION Number 0200
@@01 Near _TEXT:0079
@@02 Near _TEXT:0086
@@03 Near _TEXT:008D
@CODE Text _TEXT
@CODESIZE Text 0
@CPU Text 0101H
@CURSEG Text _DATA
@DATA Text DGROUP
@DATASIZE Text 0
@FILENAME Text Q184122
@MODEL Text 2
@WORDSIZE Text 2
ATRRIB Number 007F
BEGIN Near _TEXT:0000
BIT3_0 Number 000F
BIT6_4 Number 0070
BIT7 Number 0000
CURRENTNUMBER Number 0064
DBARRAY Byte DGROUP:0000
DWARRAY Word DGROUP:005A
DWFORMAT Number [DGROUP:BP+0004]
DWNUMBER Number [DGROUP:BP+0006]
DWRESULT Number [DGROUP:BP+0004]
MAINLOOP Near _TEXT:0017
MOVELOOP Near _TEXT:002F
SHOWDATA Near _TEXT:0040
SHOWNUMBER Near _TEXT:006E
SZARRAY Number 005A

Groups & Segments Bit Size Align Combine Class

DGROUP Group
STACK 16 0100 Para Stack STACK
_DATA 16 005A Word Public DATA
_TEXT 16 009A Word Public CODE[/code]
добавляю листинг компиляции, Вы увидете, что и как компилируется.
Об авторе:
Мне безразлично, что Вы думаете о обо мне, но я рад за Вас - Вы начали думать.

Форма ответа