Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Низкоуровневое программирование > Assembler - Ассемблер (FASM, MASM, WASM, NASM, GoASM, Gas, RosAsm, HLA) и не рекомендуем TASM
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 02.06.2011, 16:17   #1
duk0077
Новичок
Джуниор
 
Регистрация: 02.06.2011
Сообщений: 5
По умолчанию задача под Masm32

Подскажите пожалуйста, где ошибка, точнее скорее всего она в процедуре печати, но каким образом её исправить, не знаю. Дан массив Z dw 30 DUP(?) нужно последний положительный элемент в нём занулить.

; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤ ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤ ¤¤¤
include \masm32\include\masm32rt.inc
; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤ ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤ ¤¤¤


.data
z dw 30 DUP(?)
.code

start:

; \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ \\\\\\\\\\\\\\\\\\\\\\\\

call zapolnenie
call pech
call main
call pech
inkey
exit

;\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\

zapolnenie proc
cls ;чистим экран
mov cx,0 ;инициализируем счётчик
.WHILE (cx!=29) ;пускаем цикл пока счётчки не будет равен 0
mov ax,cx ;загружаем в акамулятор счётчик для умножения
mov si,16 ;подготавливаем множитель для сдвига
mul si ;вычисляем сдвиг
mov [z+ax],cx ;заполняем массив
inc cx ;инкрементируем счётчик
.ENDW ;заканчиваем цикл
ret

zapolnenie endp

; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤ ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤ ¤¤¤

pech proc
mov cx,0 ;инициализируем счётчик
.WHILE (cx!=29) ;пускаем цикл пока счётчки не будет равен 0(бежим по масиву)
mov ax,cx ;загружаем в акамулятор счётчик для умножения
mov si,16 ;подготавливаем множитель для сдвига
mul si ;вычисляем сдвиг
mov bx,[z+ax] ;закидываем элемент массива в регистр для печати
print str$(bx),13,10 ;печатаем элемент
inc cx ;инкрементируем счётчик
.ENDW ;заканчиваем цикл
ret

pech endp


; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤ ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤ ¤¤¤

main proc
mov cx,0 ;инициализируем счётчик
.WHILE (cx!=29) ;пускаем цикл пока счётчки не будет равен 0(бежим по масиву)
mov ax,cx ;загружаем в акамулятор счётчик для умножения
mov si,16 ;подготавливаем множитель для сдвига
mul si ;вычисляем сдвиг
.IF ([z+ax]>0) ;если элемент положительный
mov bx,ax ;сохраняем индекс(смещение)
.ENDIf
inc cx ;инкрементируем счётчик
.ENDW
mov [z+bx],0 ;обнуляем последний положительный элемент за счёт сохранённого сдвига
ret

main endp

; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤ ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤ ¤¤¤

end start

Последний раз редактировалось duk0077; 02.06.2011 в 18:23.
duk0077 вне форума Ответить с цитированием
Старый 02.06.2011, 21:07   #2
HmL
Пользователь
 
Регистрация: 13.05.2011
Сообщений: 17
По умолчанию

Цитата:
print str$(bx),13,10 ;печатаем элемент
Нужно передавать 32-х разрядный регистр. Старшие биты необходимо обнулить.
Регистр ecx необходимо сохранить перед вызовом процедуры, поскольку она его "портит".

Цитата:
mov [z+ax],cx ;заполняем массив
Происходит выход за пределы массива.
HmL вне форума Ответить с цитированием
Старый 02.06.2011, 21:33   #3
duk0077
Новичок
Джуниор
 
Регистрация: 02.06.2011
Сообщений: 5
По умолчанию

Цитата:
Сообщение от HmL Посмотреть сообщение
Регистр ecx необходимо сохранить перед вызовом процедуры, поскольку она его "портит".
.
А насчёт "портит", можно поточнее, каким образом?
duk0077 вне форума Ответить с цитированием
Старый 02.06.2011, 21:38   #4
HmL
Пользователь
 
Регистрация: 13.05.2011
Сообщений: 17
По умолчанию

С процедурой print я не знаком, но как и некоторые другие процедуры она записывает некоторые данные в регистр ecx, что приводит к тому, что цикл будет выполняться бесконечное количество раз или больше заданного.
Это все можно увидеть в отладчике.
HmL вне форума Ответить с цитированием
Старый 02.06.2011, 21:43   #5
duk0077
Новичок
Джуниор
 
Регистрация: 02.06.2011
Сообщений: 5
По умолчанию

Огромное спасибо, я просто за масм только вчера вечером сел, и не очень ещё освоился, а не подскажешь, почему могут не работать прерывания?
Исправил евх и сх, всё равно где-то косяк

pech proc
mov cx,0 ;инициализируем счётчик
.WHILE (cx!=29) ;пускаем цикл пока счётчки не будет равен 0(бежим по масиву)
mov ax,cx ;загружаем в акамулятор счётчик для умножения
mov si,16 ;подготавливаем множитель для сдвига
mul si ;вычисляем сдвиг
mov ebx,0
mov bx,[z+ax] ;закидываем элемент массива в регистр для печати
mov dx,cx
print str$(ebx),13,10 ;печатаем элемент
mov cx,dx
inc cx ;инкрементируем счётчик
.ENDW ;заканчиваем цикл
ret

Последний раз редактировалось duk0077; 02.06.2011 в 21:48.
duk0077 вне форума Ответить с цитированием
Старый 02.06.2011, 22:19   #6
HmL
Пользователь
 
Регистрация: 13.05.2011
Сообщений: 17
По умолчанию

Вот рабочий пример.
Код:
; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤ ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤ ¤¤¤
include \masm32\include\masm32rt.inc
; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤ ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤ ¤¤¤

.data
z dw 30 DUP(?) 
.code

start:

; \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ \\\\\\\\\\\\\\\\\\\\\\\\

call zapolnenie
call pech
call main
call pech
inkey
exit

;\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\

zapolnenie proc
xor edi, edi
cls ;чистим экран
mov cx,0 ;инициализируем счётчик
.WHILE (cx!=29) ;пускаем цикл пока счётчки не будет равен 0
mov [z+edi],cx ;заполняем массив
add edi, 2
inc cx ;инкрементируем счётчик
.ENDW ;заканчиваем цикл
ret

zapolnenie endp

; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤ ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤ ¤¤¤

pech proc
xor edi, edi
xor ebx, ebx
mov cx,0 ;инициализируем счётчик
.WHILE (cx!=29) ;пускаем цикл пока счётчки не будет равен 0(бежим по масиву)
mov bx,[z+edi] ;закидываем элемент массива в регистр для печати
add edi, 2
push ecx
print str$(ebx),13,10 ;печатаем элемент
pop ecx
inc cx ;инкрементируем счётчик
.ENDW ;заканчиваем цикл
ret

pech endp


; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤ ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤ ¤¤¤

main proc
xor edi, edi
mov cx,0 ;инициализируем счётчик
.WHILE (cx!=29) ;пускаем цикл пока счётчки не будет равен 0(бежим по масиву)
.IF ([z+edi]>0) ;если элемент положительный
mov ebx,edi ;сохраняем индекс(смещение)
.ENDIf
add edi, 2
inc cx ;инкрементируем счётчик
.ENDW
mov [z+ebx],0 ;обнуляем последний положительный элемент за счёт сохранённого сдвига
ret

main endp

; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤ ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤ ¤¤¤

end start
Я убрал из процедур main и pech инструкции
Код:
mov ax,cx
mov si,16
mul si
поскольку не понял их назначения.

Последний раз редактировалось HmL; 02.06.2011 в 22:28.
HmL вне форума Ответить с цитированием
Старый 02.06.2011, 22:24   #7
duk0077
Новичок
Джуниор
 
Регистрация: 02.06.2011
Сообщений: 5
По умолчанию

погоди, а как тогда у тебя смещение по массиву идёт? ну точнее я понимаю что вычисляется смещение add edi, 2, но разве следующая от предыдущей ячейки массива в 2 байтах?
И какой тут смысл несут ксоры?

Последний раз редактировалось duk0077; 02.06.2011 в 22:29.
duk0077 вне форума Ответить с цитированием
Старый 02.06.2011, 22:40   #8
HmL
Пользователь
 
Регистрация: 13.05.2011
Сообщений: 17
По умолчанию

У вас выделяется массив на 30 элементов. Размер каждого элемента будет 2 байта. Следовательно, для доступа к следующему элементу массива необходимо увеличить индекс на 2.

Цитата:
И какой тут смысл несут ксоры?
Обнуление индекса массива. И обнуление регистра ebx, для корректной работы процедуры print.
HmL вне форума Ответить с цитированием
Старый 02.06.2011, 23:04   #9
duk0077
Новичок
Джуниор
 
Регистрация: 02.06.2011
Сообщений: 5
По умолчанию

Спасибо огромное за всё

Последний раз редактировалось duk0077; 03.06.2011 в 17:07.
duk0077 вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
борьба c masm32 Krasi Assembler - Ассемблер (FASM, MASM, WASM, NASM, GoASM, Gas, RosAsm, HLA) и не рекомендуем TASM 12 02.02.2014 05:53
MASM32, начало Delffinn Assembler - Ассемблер (FASM, MASM, WASM, NASM, GoASM, Gas, RosAsm, HLA) и не рекомендуем TASM 12 19.07.2012 19:09
Установка MASM32. Samium Assembler - Ассемблер (FASM, MASM, WASM, NASM, GoASM, Gas, RosAsm, HLA) и не рекомендуем TASM 1 19.07.2012 19:04
masm32 Katya25 Assembler - Ассемблер (FASM, MASM, WASM, NASM, GoASM, Gas, RosAsm, HLA) и не рекомендуем TASM 1 17.05.2011 08:40
MASM32 VS MASM JOFRIF Assembler - Ассемблер (FASM, MASM, WASM, NASM, GoASM, Gas, RosAsm, HLA) и не рекомендуем TASM 8 21.02.2011 06:55