Страница 1 из 2

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

Добавлено: 10 янв 2008, 02:06
roman_alexeev
Здравствуйте, уважаемые.

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

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


Заранее спасибо.

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

Добавлено: 10 янв 2008, 03:03
roman_alexeev
На С++ получается что-то вот такое:

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

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).

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

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

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

;---------------------------------------------------------------------------------
;Вычислить количество нечетных чисел в массиве из 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			;конец программы

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

Добавлено: 10 янв 2008, 20:22
somewhere
вроде да, только вот push ax и pop ax здесь не нужны

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

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

Точнее если убрать "push ax" и оставить "pop ax" - тогда работает.
А вот без "pop ax" почему то вылетает. В чем тут дело?

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

Добавлено: 11 янв 2008, 00:06
somewhere
Что то херня какая то нереальная вообще, какая именно instruction явялется illegal, компилятор/версия какие?

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

Добавлено: 11 янв 2008, 01:06
roman_alexeev
Компилятор: Turbo Assembler Version 5.1 Borland

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

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

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

Задам еще один вопрос..
А как теперь значение BL на экран вывести?

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

Добавлено: 11 янв 2008, 14:27
somewhere
Все понятно, заместо "блатных" int 20h, используйте
mov ax, 4C00h
Int 21h

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

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

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

У roman_alexeev, как я понимаю, судя по наличию нескольких сегментов, EXE-шник. Вероятно, в его случае CS не указывает на PSP?

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

Добавлено: 11 янв 2008, 16:12
somewhere
&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 указывает в какие то долбеня, либо у него просто обработчика нет.