Хостинг портала RFpro.ru: Московский хостер Профессиональный ХОСТИНГ на базе Linux x64 и Windows x64 РАССЫЛКИ ПОРТАЛА RFPRO.RU Чемпионы рейтинга экспертов в этой рассылке Номер выпуска: | 1348 | Дата выхода: | 31.05.2010, 00:00 | Администратор рассылки: | Лысков Игорь Витальевич, Модератор | Подписчиков / экспертов: | 261 / 63 | Вопросов / ответов: | 2 / 2 | IRC-канал по теме: | #assembler | Вопрос № 178625: Задать массив беззнаковых чисел в виде слов (16 бит) статически в сегменте данных. Вывести элементы массива на экран в столбик. Процессор - 8086 Ассемблер - TASM v. 2.51 Платформа - MS-DOS Модель памяти - не имеет значения Сам напи... Вопрос № 178634: Здравствуйте уважаемые эксперты. Прошу помощи. Требуется переделать пример с использованием и без использования инструкций ММХ и сравнить время их выполнения. Программа должна реализовать поиск заданного элемента в матрице (двумерный массив). ... Вопрос № 178625: Задать массив беззнаковых чисел в виде слов (16 бит) статически в сегменте данных. Вывести элементы массива на экран в столбик. Процессор - 8086 Ассемблер - TASM v. 2.51 Платформа - MS-DOS Модель памяти - не имеет значения
Сам написал код, но он работает неправильно. Укажите Ваш вариант или подскажите что исправить в моем. Отправлен: 25.05.2010, 16:36 Вопрос задал: Никифоров Павел, Посетитель Всего ответов: 1 Страница вопроса » Отвечает Лысков Игорь Витальевич, Модератор : Здравствуйте, Никифоров Павел. Подправил малость... Основная ошибка - не проинициировали сегментные регистры. По умолчанию, они равны сегменту PSP, а не сегменту DataSG, поэтому вся работа в памяти велать совершенно не по тем адресам. Кроме того, подправил на строковые команды lodsw, stosb.
Код: ;-------------------------------------------- ;Вывод массива на экран в столбик ;-------------------------------------------- DataSG SEGMENT X DW 10,15,17,32,19 lastX label word REZ_SHOW DB 10 DUP ('@'),'$' DataSG ENDS
STACKSG SEGMENT STACK ;Во-первых, надо добавлять STACK Dw 100 DUP (?) ;Во-вторых, надо слова, в-третьих, хотя бы, 100h STACKSG ENDS
CodeSG SEGMENT ASSUME CS:CODESG,DS :DATASG,SS:STACKSG
Start: ;Задание режима экрана MOV AH, 00H ; функция задания режима экрана MOV AL, 03H ; текстовый, 25 строк по 80 знаков INT 10H ;Очистка экрана прокруткой вверх - это лишнее, после инициализации режима экран и так очистится ; MOV AH, 06H ; функция прокрутки вверх ; MOV AL, 00H ; очистка всего экрана ; MOV BH, 07H ; атрибут пробела-ЧБ нормальной яркости ; MOV CX, 0000H ; верхняя левая позиция ; MOV DX, 184FH ; нижняя правая позиция (Y=24, X=79) ; INT 10H ;Установка курсора в заданную позицию - и это лишнее, по той же причине :) ; MOV AH, 02H ; функция перемещения курсора ; MOV BH, 00H ; страница 0 ; MOV DH, 00H ; строка 0 ; MOV DL, 00H ; столбец 0 ; INT 10H
mov ax, DataSG ;инициализацию сегментных регистров кто будет делать? :) mov ds, ax mov es, ax
lea si,X ; начальное значение адресамассива out_mas: lodsw ; Элемент массива в AX lea di,rez_show ; [di] = адресу буфера xor cx, cx ; обнуляем счетчик цифр mov bx, 10D ; основание системы счисления, 10 для десятичной oi2: xor dx,dx ; обнуляем регистр для хранения цифры div bx ; делим число на основание сс. В остатке (в регистре DX) получается последняя цифра push dx ; cразу выводить её нельзя, поэтому сохраним её в стеке. inc cx ; увеличиваем на 1 число цифр ;повторяем процесс до тех пор, пока частное в AX не равно 0 test ax, ax ; так покрасивее будет, чем cmp ax, 0 jnz oi2 ; Формированию строки из цифр oi3: ; чуть подправил... pop ax ; извлекаем очередную цифру из стека add al, '0' ; переводим её в символ stosb loop oi3 ;Добавляем конец строки mov ax, 0a0dh ;сразу два байта stosw mov byte ptr [di],'$' ;Выводим строку MOV AH, 09H ; номер функции изображения строки на экране LEA DX, REZ_SHOW ; загрузка адреса строки симво лов INT 21H ; Управление циклом cmp si,lastX ; если не достигнут конец массива jne out_mas ; продолжаем цикл ;-------------------------------------------- ;Выход из программы ;-------------------------------------------- MOV AX,4C00H ; задание функции выхода из программы. INT 21H ; вызов прерывания 21 CODESG ENDS END Start
----- Удачи! Ответ отправил: Лысков Игорь Витальевич, Модератор Ответ отправлен: 25.05.2010, 17:36 Номер ответа: 261639 Украина, Кировоград Тел.: +380957525051 ICQ # 234137952 Mail.ru-агент: igorlyskov@mail.ru Абонент Skype: igorlyskov
Оценка ответа: 5 Комментарий к оценке: Спасибо за советы. Про сегментные регистры забыл, надо же. Заодно изучу строковые команды, пока до них не дошел. Вам помог ответ? Пожалуйста, поблагодарите эксперта за это! Как сказать этому эксперту "спасибо"? | Отправить SMS #thank 261639 на номер 1151 (Россия) | Еще номера » | Вопрос № 178634: Здравствуйте уважаемые эксперты. Прошу помощи.
Требуется переделать пример с использованием и без использования инструкций ММХ и сравнить время их выполнения. Программа должна реализовать поиск заданного элемента в матрице (двумерный массив). Нужно переписать команды ассемблера под данное задание.
Листинг программы – примера на языке C (вычисление скалярного произведения) (Microsoft Visual C++ 6.0)
Код: #include "stdio.h" #include "windows.h" int main(int argc, char* argv[]) { short a_vect[16], b_vect[16]; short cnt = 16; int res = 0, res1 = 0; int Time1, Time2, Delay1; double Speedup; for (int i=0; i<16; i++) { a_vect[i] = 15; b_vect[i] = 7; } //printf("\nСкалярно е произведение с MMX и без...\n\n"); printf("\nScalar product with or without MMX...\n\n"); printf("\nResult = %d\n", res); printf("Result1 = %d\n", res1); // Замерить время... Time1 = GetTickCount(); // Многократный прогон с MMX ... for (i=0; i<10000000; i++) { cnt = 16; __asm { push eax push ebx push ecx push esi xor esi, esi pxor MM7, MM7 loop1: movq MM0, a_vect[esi] movq MM1, b_vect[esi] pmaddwd MM0, MM1 paddd MM7, MM0 add esi, 8 sub cnt, 4 jnz loop1 movq MM0, MM7 psrlq MM7, 32 paddd MM7, MM0 movd res, MM7 emms pop esi pop ecx pop ebx pop eax } } Time2 = GetTickCount(); //printf("\n С использованием ММХ ...\n"); printf("\n Using MMX ...\n"); printf("\nResult = %d", res); Delay1 = Time2 - Time1; printf("\nTime elapsed = %d ms\n", Delay1); // Замерить время... Time1 = GetTickCount(); //Многократный прогон кода без MMX ... for (i=0; i<10000000; i++) { cnt = 16; __asm { push eax push ebx push ecx push esi xor esi, esi xor ecx, ecx loop2: mov ax, a_vect[esi] // Чтение из памяти mov bx, b_vect[esi] mov ax, 15 //Непосредственная адресация mov bx, 7 imul ax, bx add cx, ax add esi, 2 sub cnt, 1 jnz loop2 mov res1, ecx pop esi pop ecx pop ebx pop eax } } Time2 = GetTickCount(); //printf("\n Без использования ММХ...\n"); printf("\n Without MMX ...\n"); printf("\nResult1 = %d", res1); printf("\nTime elapsed = %d ms\n", Time2 - Time1); Speedup = float((Time2 - Time1))/float(Delay1); printf("\nMMX SpeedUp = %10.4f times\n\n", Speedup); return 0; }
Отправлен: 25.05.2010, 23:16 Вопрос задал: Farrel, Посетитель Всего ответов: 1 Страница вопроса » Отвечает Лысков Игорь Витальевич, Модератор : Здравствуйте, Farrel. Получается примерно следующее (под masm32):Код: .686p .MMX .model flat, stdcall
option casemap :none ; case sensitive
;include files include \MASM32\INCLUDE\windows.inc include \MASM32\INCLUDE\gdi32.inc include \MASM32\INCLUDE\user32.inc include \MASM32\INCLUDE\kernel32.inc include \MASM32\INCLUDE\masm32.inc
;libraries includelib \MASM32\LIB\kernel32.lib includelib \MASM32\LIB\gdi32.lib includelib \MASM32\LIB\user32.lib includelib \MASM32\LIB\masm32.lib
.data sTitle DB 0aH, 'Scalar product with or without MMX...', 0aH, 0aH, 0 sResult DB 0aH, 'Result = %d', 0aH, 0 sResult1 DB 'Result1 = %d', 0aH, 0 sUsingMMX DB 0aH, ' Usin g MMX ...', 0aH, 0 sTimeElapsed DB 0aH, 'Time elapsed = %d ms', 0aH, 0 sWithoutMMX DB 0aH, ' Without MMX ...', 0aH, 0 sSpeedUp DB 0aH, 'MMX SpeedUp = %s times', 0aH, 0aH, 0
.code start: call main invoke ExitProcess, 0
main PROC local a_vect[16]:word, b_vect[16]:word local cnt:word local res:dword, res1:dword local Time1:dword, Time2:dword, Delay1:dword local SpeedUp:qword local sBuffer[256]:byte local sFloat[64]:byte
push ebx push esi push edi
;for (int i=0; i<16; i++) ;{ ; a_vect[i] = 15; ; b_vect[i] = 7; ;} mov ecx, 8 mov eax, 000f000fH lea edi, DWORD PTR a_vect rep stosd
mov ecx, 8 mov eax, 00070007H lea edi, DWORD PTR b_vect rep stosd
;res = 0 ;res1 = 0 xor esi, esi mov res, esi mov res1, esi
;printf("\nScalar product with or without MMX...\n\n") invoke StdOut, ADDR sTitle ;printf("\nResult = %d\n", res) invoke wsprintf, ADDR sBuffer, ADDR sResult, esi invoke StdOut, ADDR sBuffer
;printf("Result1 = %d\n", res1) invoke wsprintf, ADDR sBuffer, ADDR sResult1, esi invoke StdOut, ADDR sBuffer
;Замерить время... call GetTickCount mov DWORD PTR Time1, eax
mov edx, 10000000 WithMMXLoop: ;Многократный прогон с MMX ... ;for (i=0; i<10000000; i++) ;{ ; cnt = 16; mov DWORD PTR cnt, 16 push eax push ebx push ecx push esi xor esi, esi pxor MM7, MM7 loop1: movq MM0, QWORD PTR a_vect[esi] movq MM1, QWORD PTR b_vect[esi] pmaddwd MM0, MM1 paddd MM7, MM0 add esi, 8 sub cnt, 4 jne loop1
movq MM0, MM7
psrlq MM7, 32 paddd MM7, MM0 movd res, MM7 emms pop esi pop ecx pop ebx pop eax dec edx jne WithMMXLoop ;} call GetTickCount mov esi, eax
;printf( "\n Using MMX ...\n"); invoke StdOut,ADDR sUsingMMX
;printf("\nResult = %d", res); invoke wsprintf,ADDR sBuffer,ADDR sResult,res invoke StdOut,ADDR sBuffer
;Delay1 = Time2 - Time1; sub esi, Time1 mov Delay1, esi
;printf("\nTime elapsed = %d ms\n", Delay1); invoke wsprintf,ADDR sBuffer,ADDR sTimeElapsed,esi invoke StdOut,ADDR sBuffer
;Замерить время... call GetTickCount mov Time1, eax
mov edx, 10000000 WithoutMMXLoop: ;Многократный прогон кода без MMX ... ;for (i=0; i<10000000; i++) ;{ ; cnt = 16; mov cnt, 16 push eax push ebx push ecx push esi xor esi, esi xor ecx, ecx loop2: mov ax, a_vect[esi] mov bx, b_vect[esi] imul ax, bx add cx, ax add esi, 2 sub cnt, 1 jnz loop2 mov res1, ecx pop esi pop ecx pop ebx pop eax
dec edx jne WithoutMMXLoop
call GetTickCount mov esi, eax
;printf("\n Without MMX ...\n"); invoke StdOut, ADDR sWithoutMMX
;printf("\nResult1 = %d& quot;, res1);
invoke wsprintf, ADDR sBuffer, ADDR sResult1, res1 invoke StdOut, ADDR sBuffer
;printf("\nTime elapsed = %d ms\n", Time2 - Time1); sub esi, Time1 mov Time1, esi invoke wsprintf, ADDR sBuffer, ADDR sTimeElapsed, esi invoke StdOut, ADDR sBuffer
;Speedup = float((Time2 - Time1))/float(Delay1); ;printf("\nMMX SpeedUp = %10.4f times\n\n", Speedup); fild Time1 fidiv Delay1 fstp SpeedUp
;сначала преобразуем float qword в строку invoke FloatToStr, SpeedUp, ADDR sFloat ;сформируем строку invoke wsprintf, ADDR sBuffer, ADDR sSpeedUp, ADDR sFloat ;и выведем invoke StdOut, ADDR sBuffer
;return 0; xor eax, eax
;} pop edi pop esi pop ebx ret main ENDP
END start
----- Удачи! Ответ отправил: Лысков Игорь Витальевич, Модератор Ответ отправлен: 29.05.2010, 21:30 Номер ответа: 261749 Украина, Кировоград Тел.: +380957525051 ICQ # 234137952 Mail.ru-агент: igorlyskov@mail.ru Абонент Skype: igorlyskov Вам помог ответ? Пожалуйста, поблагодарите эксперта за это! Как сказать этому эксперту "спасибо"? | Отправить SMS #thank 261749 на номер 1151 (Россия) | Еще номера » | Оценить выпуск » Нам очень важно Ваше мнение об этом выпуске рассылки! Скажите "спасибо" эксперту, который помог Вам! Отправьте СМС-сообщение с тестом #thank НОМЕР_ОТВЕТА на короткий номер 1151 (Россия) Номер ответа и конкретный текст СМС указан внизу каждого ответа. Полный список номеров » * Стоимость одного СМС-сообщения от 7.15 руб. и зависит от оператора сотовой связи. (полный список тарифов) ** При ошибочном вводе номера ответа или текста #thank услуга считается оказанной, денежные средства не возвращаются. *** Сумма выплаты эксперту-автору ответа расчитывается из суммы перечислений на портал от биллинговой компании. |
Комментариев нет:
Отправить комментарий