Форум программистов, компьютерный форум, киберфорум
Assembler для начинающих
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.86/7: Рейтинг темы: голосов - 7, средняя оценка - 4.86
3 / 3 / 2
Регистрация: 02.12.2011
Сообщений: 39
1

Помогите ошибку найти

07.12.2011, 18:05. Показов 1261. Ответов 4
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
дв енедели уже эту лабу мучаю

задание такое - сформировать массив, вывести, создать второй массив,
в него поместить колличество единиц, содержащихся в двоичном представлении элементов первого массива

Первая часть отдельно работает. Вывод убрал, чтобы не мешал смотреть.
Получаются числа от 7 до 33, как и надо.

Вторая часть должна каждое число взять в двоичном представлении из памяти, посчитать кол. единиц в них и вывести сколько все единиц насчитало. Должно получится 77 единиц.
Assembler
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
.model tiny
cseg segment
ASSUME CS:cseg,DS:cseg
org 100h
 
START:
mov SI,1
mov BL,2
 
mov DH,21
mov DL,3
mov CX,20
 
a1:
mov AX,SI
mul BL
add AL,DH
mov BH,AL
div DL
mov Ah,0
mov mas[SI-1],AL
inc SI
loop a1
 
mov BL,4
mov DH,21
mov DL,3
mov CX,10
 
a2:
mov AX,SI
mul BL
sub AL,DH
mov BH,AL
div DL
mov Ah,0
mov mas[SI-1],AL
inc SI
loop a2
 
 
 
mov cx,26
 
mov si,offset mas
 
@s: 
 
mov al,[si]
 
push cx
 
xor ah,ah
mov cx,8
 
@l1: rcl al,1
adc ah,0
loop @l1
 
pop cx
inc si
 
loop  @s
 
 
 
outint proc
push cx
aam
add ax,3030h
mov dl,ah
mov dh,al
mov ah,02
int 21h
mov dl,dh
int 21h
pop cx
ret
outint endp
int 21h
 
mas db 30 dup(?)
mas2 db 30 dup(?)
cseg ends
end start
ошибка думаю в этой части

в сх кидаю 26 (33-7, кол-во элементов из первого массива)
в СИ кидаю адресс начала первого массива
внешний массив @S - беру первый элемент, в сх кидаю колличество бит
внутренний массив @l1 сдвигаю и складываю, прокручивается восемь раз
потом продолжается внешний массив, берет след элемент из первого
и прыгает вначало


Assembler
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
mov cx,26
 
mov si,offset mas
 
@s: 
 
mov al,[si]
 
push cx
 
xor ah,ah
mov cx,8
 
@l1: rcl al,1
adc ah,0
loop @l1
 
pop cx
inc si
 
loop  @s
Добавлено через 1 час 50 минут
ну хотябы намеком
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
07.12.2011, 18:05
Ответы с готовыми решениями:

Помогите найти ошибку
mov bx,00133 mov d,,004030201 add d,,040404040 mov dx,0010 mov ...

Помогите найти и исправить ошибку
#include <iostream> #define Size 5 using namespace std; int main (void) { int massiv; int...

Помогите найти ошибку в вычислении выражения
A/B - 42, если A>B -11, если А=В (A*A - 8)/A, если А<В Первые два случая работают нормально, а...

Вычисление выражения, помогите найти ошибку
Не понимаю в чём ошибка, программа должна вычисления разность 5-го и 3-го элемента...

4
3 / 3 / 2
Регистрация: 02.12.2011
Сообщений: 39
08.12.2011, 23:23  [ТС] 2
может кто у себя запустить
проверить работает или нет???
а то у меня пашет но диски не выводит
может проц не тот просто что надо

Assembler
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
puts  macro string ;вывод строки
lea dx,string
mov ah,09h
int 21h
endm
 
.model tiny
.code
org 100h
.386
start:
jmp inst
Unloaded db 'Drvinfo BblgPyGen$'
AlreadyLoaded 
db 13,10,'Drvinfo 6blJl 3agPygeH PaHee',13,10,'$'
inputdrv db 'BBeDuTe 6yKBy DucKa: $'
drv db 0 ;номер диска
wrongdrv db 13,10,'HevePHblu DucK.',13,10,'$'
rp1 db 13,10,'DucK :'
db 13,10,'O6`em: $'
rp2 db ' 6auT'
db 13,10,'CBo6oDHo: $'
rp3 db ' 6auT'
db 13,10,'Байт на сектор: $'
rp4 db 13,10,'Секторов на кластер: $'
rp5 db 13,10,'Количество копий FAT: $'
rp6 db 13,10,'Количество каталогов в корне диска: $'
rp7 db 13,10,'Количество секторов в одной копии FAT: $'
anykey        db    13,10,'Нажмите любую клавишу для продолжения$'
Sucsess        db    13,10,'Drvinfo загружен',13,10,'$'
ctrl        db    0    ;признак нажатой клавиши ctrl 0-отжата, ff - нажата
Old2D        dd    ?    ; резервируем место для адреса оригинального обработчика прерывания 2Dh
Old09        dd    ?    ; резервируем место для адреса оригинального обработчика прерывания 09h
 
scrbuf    db 4000 dup (0)        ;Область памяти для сохранения текстового экрана
old_f    dw 0            ;Регистр флагов работающей программы
mode    db 0            ;режим работы программы 0 - фоновый 1- полноэкранный
curpos    dw 0            ;текущее положение курсора.
inp    db 6,7 dup(0)        ;строка, куда вводится время будильника с клавиатуры.
 
New2DObrab    proc        ; новый обработчик прерывания int2Dh
 
   cli        ; запретить обработку маскированных прерываний (сброс флага прерывания if=0)
   pushf
   cmp    al,98h        ; проверка на то, загружен ли резидент?
   jne    ex_c    ; нет - пропускаем
   inc    al        ; устанавливаем al=99h - признак того, что резидент загружен
ex_c:    popf            ; восстановить флаги
   sti           ; разрешить прерывния
   iret          ; выход из прерывания
 
DoNothing:
 
   popf
   sti            ; установка флага прерывания if в единицу
   jmp    dword    ptr    CS:[Old2D]    ;переход на реальный обработчик прерывания
 
endp
 
New09Obrab    proc        ; новый обработчик прерывания int09h
   pushf            ; заносим флаги в стек, поскольку iret в конце оригинального обработчика заберет один экземпляр флагов из стека
   call    dword    ptr    CS:[Old09]    ; вызов оригинального обработчика
   cli            ; запретить прерывания
   pusha            ; сохранить регистры общего назначения
   push es    ; сохраняем сегментные регистры, поскольку они не сохраняются командой pusha
   push ds
   push cs            ;ds=cs
   pop    ds
   in    al,60h        ; читаем из порта клавиатуры скан-код нажатой клавиши
   cmp    al,1dh        ; если нажат CTRL
   jnz    m1
   mov    cs:ctrl,1    ;то устанавливаем флаг
m1:    cmp    al,9dh        ; если отжат CTRL
   jnz    m2
   mov    cs:ctrl,0    ;то сбрасываем флаг
m2:   cmp    al,2dh        ;нажата X
   jnz    ne_x        ;если нет, то пропустить
   cmp    cs:ctrl,0    ;если ctrl не нажата, то пропустить
   jz    ne_x
;Нажаты Ctrl+X - выгружаем резидент
   push    0b800h        ;Сегмент видеопамяти
   pop    es
   mov  bx,1920 ;адрес в видеопамяти куда будем выводить сообщение(средняя строка, начало)
   lea    si,Unloaded    ;выводимое сообщение
   mov    ah,7        ;серый цвет
outt:    mov    al,cs:[si]    ;берем символ сообщения
   cmp    al,'$'        ;если признак конца строки
   jz    outex        ;то закончить
   mov    es:[bx],ax    ;выводим прямо в видеопамять
   inc    si        ;следующий символ
   add    bx,2
   jmp    outt        ;продолжаем ввывод
outex:
   push    0        ;сегмент векторов прерываний
   pop    es
   mov    ax,word ptr CS:Old09    ; восстановление векторов прерываний
   mov    es:[24h],ax
   mov    ax,word ptr CS:Old09+2
   mov    es:[26h],ax
   mov    ax,word ptr CS:Old2d
   mov    es:[0b4h],ax
   mov    ax,word ptr CS:Old2d+2
   mov    es:[0b6h],ax
   mov    ax,CS:[2Ch]    ; сегмент переменных окружения
   dec    ax        ;его MCB
   mov    es,ax
   mov    es:[1],word ptr 0    ;Записываем блока Owner=0, значит блок свободен
   mov    ax,CS        ; сегмент самого резидента
   dec    ax          ;его MCB
   mov    es,ax
   mov    es:[1],word ptr 0    ;Записываем блока Owner=0, значит блок свободен
   jmp    skipwork
ne_x:  cmp    al,1Fh        ;нажата S
   jnz    skipwork        ;если нет, то пропустить
   cmp    cs:ctrl,0    ;если ctrl не нажата, то пропустить
   jz    skipwork
   jmp    newmode        ;Переход если Ctrl+S
 
skipwork:
   pop    ds        ; восстанавливаем сегментные регистры
   pop    es
   popa            ; восстанавливаем регистры общего назначения
   sti            ; разрешить прерывания
   iret            ; выход из прерывания
 
;Начинаем запуск программы
newmode:
   mov al,mode
   cmp al,1    ;программа уже активирована?
   jz skipwork        ;если да, то просто прыгаем на реальный обработчик таймера
   mov mode,1    ;программа активирована
   push bp        ; Теперь сохраняем адрес возврата в текущую прогамму
   mov bp,sp
   mov ax,[bp+22]
   mov old_ip,ax
   mov ax,[bp+24]
   mov old_cs,ax
   mov ax,[bp+26]
   mov old_f,ax    ; и ее флаги, чтобы когда мы закроем информацию о диске, можно было вернуться в программу пользователя
   mov word ptr [bp+22],offset infomode    ;подменяем в стеке адрес возврата из прерывания на адрес программы ввода диска
   mov [bp+24],cs
   pop bp
   jmp skipwork        ;завершаем прерывание
 
infomode:   ;Режим
 
   push es    ;Сохраняем регистры
   push ds       
   pushad
 
   push cs    ; настраиваем регистр данных
   pop ds
   mov ah,0fh
   int 10h
   cmp al,03    ;Текущий режим экрана текстовый?
   jnz bad_mode    ;если нет - то не запускаем 
 
   mov ax,0b800h    ;Сегмент экранной памяти для прямого доступа
   mov es,ax
   mov cx,2000
   lea si,scrbuf    ;Сохраняем экран в зарезервированный буфер
   xor di,di
zz1:    mov ax,es:[di]
   mov [si],ax
   inc si
   inc si
   inc di
   inc di
   loop zz1
   mov cx,2000    ;очищаем экран
   xor di,di
   mov ax,0f20h
   repnz stosw
   push cs        ;es=cs
   pop es
   mov ah,3
   mov bh,0
   int 10h        ;берем текущие координаты курсора
   mov curpos,dx    ;сохраняем их
   mov dx,0
   mov ah,2
   int 10h        ;устанавливаем курсор в верхний левый угол
inpdrv:
   puts inputdrv    ;выводим сообщение с просьбой ввести букву диска
   mov ah,1
   int 21h        ;ожидаем ввода символа с клавиатуры
   and al,1fh    ;оставляем только младшие биты символа(номер диска 1-A,2-B...)
   test al,al    ;если это ноль(расширенный код)
   jnz cont2
   mov ah,1    ;то читаем второй код расширенного кода
   int 21h     ;из буфера клавиатуры
   jmp inpdrv    ;и просим снова ввести букву диска
cont2:    mov drv,al    ;сохраняем номер диска
   mov dl,al
   add al,40h   ;преобразуем номер диска в букву
   mov rp1+7,al    ;добавляем ее в сообщение
   mov ah,32h    ;Функция получения параметров диска
   int 21h        ;получаем параметры диска
   cmp al,0ffh    ;если ff - значит такого диска нет
   jnz cont1
   puts wrongdrv    ;выводим ошибку
   jmp inpdrv    ;и просим ввести диск заново
cont1:    push ds
   pop es        ;es=ds
   push cs
   pop ds        ;ds=cs
   push bx        ;сохраняем смещение адреса блока данных о диске
   puts rp1    ;выводим первое сообщение
   mov ah,36h    ;информация о размере диска
   mov dl,drv    ;номер диска
   int 21h        ;получаем информацию о размере
;  INT 21 - DISK SPACE
;    AH = 36H
;    DL = DRIVE NUMBER (1-4)
;    Return: AX = ? (SIDES)
;        BX = ? (BLOCKS FREE)
;        CX = ? (BLOCK SIZE)
;        DX = ? (TOTAL BLOCKS)
;NOTE: MULT AX x CX x BX for FREE SPACE ON DISK
;MULT AX x CX x DX for TOTAL DISK SPACE
 
   movzx eax,ax    ;расширяем полученные параметры до 32 бит
   movzx ebx,bx
   movzx ecx,cx
   movzx edx,dx
   push eax    ;сохраняем параметры
   push ebx
   push ecx
   mul edx        ;AX x CX x DX for TOTAL DISK SPACE
   mul ecx        ;в eax получаем размер диска
   call printdec32    ;выводим его на экран
   puts rp2    ;выводим второе сообщение
   pop ecx        ;восстанавливаем данные о размере диска
   pop ebx
   pop eax
   mul ebx     ;MULT AX x CX x BX for FREE SPACE ON DISK
   mul ecx     ;получаем свободный объем
   call printdec32 ;выводим его на экран
   puts rp3    ;выводим третье сообщение
   pop bx        ;восстанавливаем адрес блока данных(полных адрес находится в es:bx)
   mov ax,es:[bx+2];берем из блока количество байт на сектор
   call printdec    ;выводим на экран
   puts rp4    ;выводим 4-е сообщение
   movzx ax, byte ptr es:[bx+4];берем из блока количество секторов в кластере
   call printdec        ;выводим на экран
   puts rp5    ;выводим 5-е сообщение
   movzx ax, byte ptr es:[bx+8];берем из блока количество копий FAT
   call printdec        ;выводим на экран
   puts rp6        ;выводим 6-е сообщение
   mov ax, es:[bx+9]    ;берем из блока количество копий FAT
   call printdec      ;выводим на экран
   puts rp7        ;выводим 7-е сообщение
   movzx ax, byte ptr es:[bx+15]    ;берем из блока количество секторов в одной копии FAT
   call printdec          ;выводим на экран
 
 
   puts anykey        ;выводим сообщение с просьбой о нажатии любой клавиши
   mov ah,0
   int 16h        ;ожидаем нажатия любой клавиши
 
 
back:    push 0b800h
   pop es
   mov cx,2000    ;восстанавливаем экран
   lea si,scrbuf
   xor di,di
   repnz movsw
   mov ah,2
   mov bh,0
   mov dx,curpos
   int 10h        ;восстанавливаем прежнее положение курсора
bad_mode:
   mov mode,0    ;фоновый режим
   push [old_f]  ;восстанавливаем флаги
   popf
   popad        ; восстанавливаем регистры
   pop ds       ; помещаем значение регистра ds в стек
   pop es               ; записываем в es число из стека
 
;возвращаемся к прерванной программе
   db  0EAh         ; опкод far jump
old_ip    dw 0            ;на прерванную программу пользователя
old_cs    dw 0
endp
 
;преобразование числа из ах в десятичную систему и вывод
printdec proc    ;преобразование и вывод числа из ах
       ;ax - число
   push cx    ;сохраняем регистры
   push dx
   push bx
   push si
   xor si,si    ;обнуляем флаг отрицательного числа
   mov bx,10    ;основание системы
   XOR CX,CX    ;в сх будет количество цифр в десятичном числе
   test ax,ax    ;число отрицательное
   jns @@m1    ;если да
   neg ax        ;то меняем знак
   inc si        ;устанавливаем признак отрицательности
@@m1:    XOR dx,dx
   DIV bx        ;делим число на степени 10
   PUSH DX        ;и сохраняем остаток от деления(коэффициенты при степенях) в стек
   INC CX
   TEST AX,AX
   JNZ @@m1
   test si,si    ;если число отрицательное
   jz @@m22
   push -3        ;то в начале ставим знак минус
   inc cx
@@m22:    mov ah,2
@@m2:    POP DX
   ADD DL,'0'    ;преобразовываем число в ASCII символ
   int 21h        ;выводим его
   LOOP @@m2        ;все цифры
   pop si
   pop bx        ;восстанавливаем регистры
   POP dx
   POP cx
   RET
printdec endp
 
printdec32 proc    ;преобразование числа из ах в десятичную строку по адресу es:di
       ;eax - число
   push ecx    ;сохраняем регистры
   push edx
   push ebx
   mov ebx,10    ;основание системы
   XOR ecx,ecx    ;в сх будет количество цифр в десятичном числе
@m1:    XOR edx,edx
   DIV ebx        ;делим число на степени 10
   PUSH edx    ;и сохраняем остаток от деления(коэффициенты при степенях) в стек
   INC ecx
   TEST eax,eax
   JNZ @m1
   mov ah,2
@m2:    POP edx
   ADD DL,'0'    ;преобразовываем число в ASCII символ
   int 21h
   LOOP @m2        ;все цифры
   pop ebx        ;восстанавливаем регистры
   POP edx
   POP ecx
   RET
printdec32 endp
 
inst:            ; загрузка резидента
; оставляем резидент в памяти
NoParameters:
 
   mov    AL,98h        ; загружен ли резидент?
   int    2Dh        ; Служебное прерывание
   cmp    AL,99h
    je   TSRAlreadyLoaded; выход, чтобы избежать повторной загрузки
 
   mov    ax,3509h    ; GetVector
   int    21h
   mov    word ptr Old09,BX
   mov    word ptr Old09+2,ES
   mov    ax,2509h    ; SetVector
   mov    dx,offset New09Obrab
   int    21h
 
   mov    ax,352Dh    ; GetVector
   int    21h
   mov    word ptr Old2D,BX
   mov    word ptr Old2D+2,ES
   mov    ax,252Dh    ; SetVector
   mov    dx,offset New2DObrab
   int    21h
 
   puts    Sucsess        ; сообщение об успехе
 
   
   mov    dx,(inst-start+100h); указываем системе сколько памяти в параграфах занимает наш резидент
   int    27h        ; закончить, но остаться в памяти
   
 
TSRAlreadyLoaded:
   puts    AlreadyLoaded    ;Резидент уже загружен
Quit:
   mov    ah,4ch        ; стандартный выход из программы
   int    21h
 
   end    start
0
Клюг
7675 / 3190 / 382
Регистрация: 03.05.2011
Сообщений: 8,380
08.12.2011, 23:58 3
Цитата Сообщение от frenzyice
ну хотябы намеком
стр. 58,59, первый листинг.
Assembler
1
2
adc ah,0
loop @l1
ты получил в AH кол-во единичек в байте. А дальше?
после loop @1
Assembler
1
2
shr ax,8
add [сумма_всех_единичек_в_массиве], ax
0
3 / 3 / 2
Регистрация: 02.12.2011
Сообщений: 39
12.12.2011, 11:42  [ТС] 4
Я про последний код
тот уже сделал все гут
0
Ушел с форума
Автор FAQ
16338 / 7659 / 1075
Регистрация: 11.11.2010
Сообщений: 13,698
13.12.2011, 03:49 5
Цитата Сообщение от frenzyice Посмотреть сообщение
Я про последний код
тот уже сделал все гут
Экстрасенсы просто тихо фигеют в углу... frenzyice, а нам-то как об этом догадаться?
0
13.12.2011, 03:49
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
13.12.2011, 03:49
Помогаю со студенческими работами здесь

Работа со строкой - помогите найти ошибку
Не могли бы помочь найти ошибку. В проге ввожу двоичное число без эха посимвольно с предварительной...

Программа пишет ошибку!! Помогите найти ошибку
Program Summa; var i, N, M: integer; begin Writeln ('Введите значение N:'); Read (N); ...

Помогите найти ошибку: По двум сторонам и углу найти все остальное
Доброго времени суток. В универе дали задание написать программу "По двум сторонам и углу между...

Найти коэффициент при 10 степени в разложении бинома Ньютона (помогите найти ошибку).
"После умножения скобок и приведения подобных в полиноме будет слагаемое с x**10. Перед ним стоит...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
5
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru