Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: QB45+ASM (MASM51) сбой в подпрограммах на ASM  (Прочитано 6987 раз)
0 Пользователей и 2 Гостей смотрят эту тему.
Paul3
Гость
« : 02-09-2004 08:28 » 

Уважаемые Господа!
Требуется Ваша помощь.
Я работаю с QB45. Разрисовываю экран в 118h режиме. Очень интересное занятие, скажу я Вам.
Однако, встретился с проблемой, которая заключается в том, что ассемблерные подпрограммы, которые вызывает Basic программа, работают очень не стабильно (их несколько, и выполняют они разные функции: рисуют всякий разный фон, разноцветные квадраты, прямоугольники, линии и пр.).
Нестабильность проявляется в том, что одна и та же картинка, например, в режиме 112h рисуется, а в режиме 118h – нет. Она начинает рисоваться, доходит до определенного места в программе, и зависает. Причем, иногда, очень глухо зависает. Иногда только тяжелая перезагрузка помогает. Кроме того, и в режиме 112h не все благополучно.
Более того. Если в той же программе на Basic добавить или убрать один или несколько операторов, то зависание случается уже в другом месте, или подпрограмма не реагирует на передаваемые ей параметры и начинает рисовать, допустим, прямоугольник, совсем не в требуемом месте экрана, а где её хочется.  

Вот фрагменты программ:

BASIC-программа
‘ ASM-подпрограмма рисования одного пикселя
DECLARE SUB aPSET (X1%, Y1%, Size%, Red%, Green%, Blue%)
. . .
Size%= MODEINFO.BytesPerScanLine            ‘ 1024
. . .
call aPSET (Colon%, Row%, Size%, 128, 128, 128)
. . .
END

Компилируется с помощью BC.EXE, которая входит в пакет QB45
X:\Quickb.4_5\bc.exe %1,%1,%1
После создания библиотеки ASM-модулей, линкуется с помощью:
X:\Quickb.4_5\link /NOI %1,%1,%1,bcom45+qb+mylib.lib

А вот одна из ASM подпрограмм:
; MASM 5.1
; Name   aPSET - рисование одного пикселя
;
; Params:
; X         - Координата Х
; Y         - Координата Y
; ScanLine  - Размер линии сканирования в байтах; uRed      - Красная компонента цвета
; uGreen    - Зелёная компонента цвета
; uBlue     - Синяя компонента цвета
;
; Return    - нет
;

.MODEL  medium,BASIC

include ASMParam.inc
include Macros.inc

.DATA

BytesPerPixel     dw  4        ; Количество байт на пиксель
WinOffSet          dw  0        ; Текущее значение смещения
WinPos              dw  0        ; Текущее значение положения окна А
ScanWidth         dw  0        ; Размер линии сканирования


; Параметры, передаваемые через стек
uBlue              EQU   WORD  PTR [bp+6]
uGreen           EQU   WORD  PTR [bp+8]
uRed              EQU   WORD  PTR [bp+10]
ScanLine         EQU   WORD  PTR [bp+12]
Y                   EQU   WORD  PTR [bp+14]
X                   EQU   WORD  PTR [bp+16]

.CODE

PUBLIC            APSET
APSET             PROC    FAR

        push    bp           ; Сохранить предыдущее значение ВР
        mov     bp, sp       ; Установить ВР для этой процедуры

        ;sub     sp, 256
        ;mov     ax, @data
        ;mov     ds, ax


        ; Установить стартовый номер окна А
        sub     ax,ax
        mov     ax, SEG_VGA      ; 0A000h – находится в ASMParam.inc
        mov     es,ax

        xor     ax, ax
        xor     bx, bx
        xor     dx, dx

        ; Расчёт смещения = Y * BytesPerScanLine + X * BytesPerPixel
        mov     bx, ScanLine ; Считать значение BytesPerScanLine
        mov     ax, [bx]   ;
        mov     ScanWidth,ax
        mov     bx, Y           ; Считать значение Y
        mov     ax, [bx]        ; ax = Y
        mul     ScanWidth       ; dx:[ax] = Y * BytesPerScanLine

        push    dx              ; Запомнить dх, показывающий
                      ; не скорректированную позицию окна А
        mov     bx, ax          ; Запомнить ax (остаток) в bx
        push    bx

        xor     ax, ax          ; Обнулить ax
        mov     bx, X           ; Считать значение Х
        mov     ax, [bx]
        mov     cl, 2
        shl     ax, cl           ; ax = X * BytesPerPixel

        and     ax, 07FFFh       ; Обнулить старший разряд
        pop     bx
        add     ax, bx          ; Сложить старое и новое значение ax
                 ; и получить смещение

        pop     dx
        jnc     SHORT SWITCHWIN ; Если при сложении ax и bx не было
                  ; переполнения (нет переноса),
                 ; то переход по метке SWITCHWIN
                                ; В этом случае в DX - точное значение окна А
                 ; В противном случае (есть единица переноса)
                 ; номер окна = номер окна + 1
        inc     dx        ; dx = dx + 1
      SWITCHWIN:
        mov     WinPos, dx

        mov     WinOffSet, ax
        @SetWindow WinPos       ; Установить новое окно.
                                      ; Макрос находится в Macros.inc
                       ; Номер окна хранится в dx
; Текст макроса "Установить новую позицию окна"
;@SetWindow   MACRO   WinPos
;      xor   ax,ax
;      mov   ax,SWITCH_WIN ; SWITCH_WIN в ASMParam.inc
  ; SWITCH_WIN DW 4F05H
;      mov   bx,0000h
;      mov   dx,WinPos
;      int   10h
;      ENDM

        ; Нарисовать пиксель
              xor     bx,bx
        mov     di,WinOffSet    ; Установить смещение в окне
             ; Достать значения компонент цвета
             ; и занести их по установленному смещению
        mov     bx, uBlue
        mov     ax, [bx]
        mov     es:[di],al
        mov     bx, uGreen
        mov     ax, [bx]
        mov     es:[di+1],al
        mov     bx, uRed
        mov     ax, [bx]
        mov     es:[di+2],al

        mov   sp, bp  ; Восстановить SP, выбросив из
                 ; стека все переменные
        pop   bp      ; Восстановить ВР BASIC-программы

        ret   12      ; Вернуться, удалив 6 параметров из стека

APSET             ENDP
END               APSET

;/////////////////////////////////////////////////////////////////////////

Эта подпрограмма (и другие ASM - подпрограммы) помещается в библиотеку mylib.lib c помощью следующего ВАТ-файла:
CLS
d:\masm51\masm /Dmodel=MEDIUM /Dlang=BASIC %1,%1,%1,%1
IF NOT ERRORLEVEL 1 d:\masm51\lib mylib.lib-%1, mylib.lst, mylib.lib
IF NOT ERRORLEVEL 1 d:\masm51\lib mylib.lib+%1, mylib.lst, mylib.lib

Подскажите пожалуйста. Что не так? Где нет стыковки?
Что нужно исправить, чтобы ASM подпрограммы заработали четко.

Заранее благодарю.
Записан
RXL
Технический
Администратор

Offline Offline
Пол: Мужской

WWW
« Ответ #1 : 03-03-2005 19:40 » 

Приглядись к этим строкам:
; Расчёт смещения = Y * BytesPerScanLine + X * BytesPerPixel
        mov     bx, ScanLine ; Считать значение BytesPerScanLine
        mov     ax, [bx]   ;

        mov     ScanWidth,ax
        mov     bx, Y           ; Считать значение Y
        mov     ax, [bx]        ; ax = Y

        mul     ScanWidth       ; dx:[ax] = Y * BytesPerScanLine

ScanLine         EQU   WORD  PTR [bp+12]
Y                EQU   WORD  PTR [bp+14]

Результат трансляции макросов примерно такой:
; Расчёт смещения = Y * BytesPerScanLine + X * BytesPerPixel
        mov     bx, WORD  PTR [bp+12] ; Считать значение BytesPerScanLine
        mov     ax, [bx]   ;
        mov     ScanWidth,ax
        mov     bx, WORD  PTR [bp+14]           ; Считать значение Y
        mov     ax, [bx]        ; ax = Y
        mul     ScanWidth       ; dx:[ax] = Y * BytesPerScanLine

См.: ты считал значение Y в bx, а потом использовал его как смещение в сегменте DS для загрузки совсем другого значения из памяти.
Советую просмотреть программу с начала и до конца на предмет подобных ошибок.
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
p0et
Гость
« Ответ #2 : 07-04-2005 00:30 » 

к RXL ответу могу только добавить
При использовании функций на асме в языках высокого уровня надо просмотреть инфу по компилятору. в твоем случае по qb45 !!! очень часто компиляторы накладывают дополнительные условия на использование асма. У меня из-за  этого возникали такие же ошибки, как у тебя, когда в зависимости от си кода, ошибки в асме то появляются то нет. кстате ошибки появлялись и в си.
Записан
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines