Простая задачка по ассемблеру.

За вознаграждение или нахаляву (если повезёт)

Модераторы: Хыиуду, MOTOCoder, Medved, dr.Jekill

Аватара пользователя
roman_alexeev
Сообщения: 6
Зарегистрирован: 10 янв 2008, 01:59
Контактная информация:

Здравствуйте, уважаемые.

Если не сложно, помогите пожалуйста с задачкой на ассемблере.
Задачка элементарная, на Си пять строчек, но с ассемблером к сожалению не знаком:

Составить программу подсчета количества нечетных чисел в массиве из 15 целых
чисел.


Заранее спасибо.
Аватара пользователя
roman_alexeev
Сообщения: 6
Зарегистрирован: 10 янв 2008, 01:59
Контактная информация:

На С++ получается что-то вот такое:

Код: Выделить всё

int main()
{
	int array[] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14};
	int count=0;
	for(int i=0; i<14; i++)
		if((array[i] % 2)==1)
			count++;
	return count;
}


Подозреваю, что на ассемблере будет попроще нечетное число искать (там вроде побитово вычислить можно).

Пробовал смотреть дизассемблированный код в отладчике - не разберусь что к чему.

Кто может помогите пожалуйста перевести на асм (под DOS на х86).
.NET Software Developer
Аватара пользователя
roman_alexeev
Сообщения: 6
Зарегистрирован: 10 янв 2008, 01:59
Контактная информация:

Ну ладно, что то накалякалось. Скажите хотя бы - это правильно? (А то на экран выводить еще не научился) ))

Код: Выделить всё

;---------------------------------------------------------------------------------
;Вычислить количество нечетных чисел в массиве из 15 целых чисел.
;----------------------------------------------------------------------------------
DATA SEGMENT
Array  DB  0,1,2,3,4,5,6,7,8,9,10,11,12,13,14
DATA ENDS
;------------------------------------------------------------------------------------
STK SEGMENT         
DB      100 dup (?) 
STK ENDS
ASSUME DS :D ATA, SS: STK, CS: CODE
;--------------------------------------------------------------------------------------


CODE SEGMENT              	;открыть сегмент кода

Start:				;начало программы
	mov cx,15 		;обрабатывать пятнадцать элементов массива
	mov si,offset Array 	;ссылаемся на первый элемент массива
	cld 			;обнуляем флаг направления чтобы регистр SI увеличивался после операции LODSB
	xor bx,bx 		;обнуляем счетчик нечетных чисел

LoopInc:			;начало работы с элементом
	lodsb 			;читаем очередной элемент в регистр AL
	push ax 		;сохраняем в стеке регистр АХ
	shr al,1			;сдвигаем вправо на один бит, в CF будет младший бит, для нечетного числа он будет равен 1
	pop ax 			;востанавливаем регистр
	jnc noInc 		;проверяем флаг CF
	inc bl 			;увеличиваем счетчик нечетных чисел
noInc: 				;если четное, просто переходим к следующему элементу
	loop LoopInc 		;цикл увеличения счетчика

	int 20h			;выход в дос
code ends			;конец сегмента кода
end Start			;конец программы
.NET Software Developer
Аватара пользователя
somewhere
Сообщения: 1858
Зарегистрирован: 31 авг 2006, 17:14
Откуда: 71 RUS
Контактная информация:

вроде да, только вот push ax и pop ax здесь не нужны
It's a long way to the top if you wanna rock'n'roll
Аватара пользователя
roman_alexeev
Сообщения: 6
Зарегистрирован: 10 янв 2008, 01:59
Контактная информация:

somewhere писал(а):вроде да, только вот push ax и pop ax здесь не нужны
Я тоже не пойму зачем сохранять в стек АХ.
Но вот почему то без них прога компилируется но не работает. Говорит "illegal instruction".

Точнее если убрать "push ax" и оставить "pop ax" - тогда работает.
А вот без "pop ax" почему то вылетает. В чем тут дело?
.NET Software Developer
Аватара пользователя
somewhere
Сообщения: 1858
Зарегистрирован: 31 авг 2006, 17:14
Откуда: 71 RUS
Контактная информация:

Что то херня какая то нереальная вообще, какая именно instruction явялется illegal, компилятор/версия какие?
It's a long way to the top if you wanna rock'n'roll
Аватара пользователя
roman_alexeev
Сообщения: 6
Зарегистрирован: 10 янв 2008, 01:59
Контактная информация:

Компилятор: Turbo Assembler Version 5.1 Borland

CPU has encountered an illegal instruction.
CS:0504 IP:06a2 OP:ff ff eb 05 ea

- Это уже в процессе выполнения, если не выполнить в процессе работы хотя бы один POP. Бред какой-то.

Ну по идее должно если работать так и оставлю, я перед преподом компилировать ниче не буду, пусть докажет что неправильно )

Задам еще один вопрос..
А как теперь значение BL на экран вывести?
.NET Software Developer
Аватара пользователя
somewhere
Сообщения: 1858
Зарегистрирован: 31 авг 2006, 17:14
Откуда: 71 RUS
Контактная информация:

Все понятно, заместо "блатных" int 20h, используйте
mov ax, 4C00h
Int 21h
It's a long way to the top if you wanna rock'n'roll
BBB
Сообщения: 1298
Зарегистрирован: 27 дек 2005, 13:37

somewhere писал(а):Все понятно, заместо "блатных" int 20h, используйте
mov ax, 4C00h
Int 21h
Int 20h для COM-файлов годится? У меня с ним (на COM-файлах) проблем никогда не было.

Посморел в interrupt list описание на Int 20h, там, в частности, указано, что:
CS = PSP segment

У roman_alexeev, как я понимаю, судя по наличию нескольких сегментов, EXE-шник. Вероятно, в его случае CS не указывает на PSP?
Аватара пользователя
somewhere
Сообщения: 1858
Зарегистрирован: 31 авг 2006, 17:14
Откуда: 71 RUS
Контактная информация:

&quot писал(а):Int 20h для COM-файлов годится? У меня с ним (на COM-файлах) проблем никогда не было.
&quot писал(а):CPU has encountered an illegal instruction.
CS:0504 IP:06a2 OP:ff ff eb 05 ea
Здесь понятно, что человек испульзует виндовый эмулятор. Int 20h нормально работет даже если CS не указывает на PSP. Просто эмулятор его либо не поддерживает, либо поддерживает но не до конца. Т.е. иллегал инстукшн возникает в результате того, что вектор 20h указывает в какие то долбеня, либо у него просто обработчика нет.
It's a long way to the top if you wanna rock'n'roll
Ответить