Отправляет email-рассылки с помощью сервиса Sendsay
  Все выпуски  

RFpro.ru: Ассемблер? Это просто! Учимся программировать


Хостинг портала RFpro.ru:
Московский хостер
Профессиональный ХОСТИНГ на базе Linux x64 и Windows x64

РАССЫЛКИ ПОРТАЛА RFPRO.RU

Чемпионы рейтинга экспертов в этой рассылке

Boriss
Статус: Академик
Рейтинг: 2420
∙ повысить рейтинг »
_Ayl_
Статус: Профессионал
Рейтинг: 1845
∙ повысить рейтинг »
vladisslav
Статус: 6-й класс
Рейтинг: 1227
∙ повысить рейтинг »

/ КОМПЬЮТЕРЫ И ПО / Программирование / Assembler (Ассемблер)

Номер выпуска: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 (Россия) | Еще номера »
  • Отправить WebMoney:

  • Вопрос № 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 (Россия) | Еще номера »
  • Отправить WebMoney:

  • Оценить выпуск »
    Нам очень важно Ваше мнение об этом выпуске рассылки!

    Задать вопрос экспертам этой рассылки »

    Скажите "спасибо" эксперту, который помог Вам!

    Отправьте СМС-сообщение с тестом #thank НОМЕР_ОТВЕТА
    на короткий номер 1151 (Россия)

    Номер ответа и конкретный текст СМС указан внизу каждого ответа.

    Полный список номеров »

    * Стоимость одного СМС-сообщения от 7.15 руб. и зависит от оператора сотовой связи. (полный список тарифов)
    ** При ошибочном вводе номера ответа или текста #thank услуга считается оказанной, денежные средства не возвращаются.
    *** Сумма выплаты эксперту-автору ответа расчитывается из суммы перечислений на портал от биллинговой компании.


    © 2001-2010, Портал RFpro.ru, Россия
    Авторское право: ООО "Мастер-Эксперт Про"
    Автор: Калашников О.А. | Программирование: Гладенюк А.Г.
    Хостинг: Компания "Московский хостер"
    Версия системы: 2010.6.16 от 26.05.2010

    В избранное