Я не понял, что не так с этим примером сборки - PullRequest
1 голос
/ 03 мая 2020

Я сделал простой пример прокрутки BMP и не понял две вещи:

1. почему изображение начинается с середины

2. почему после изменения x на экране появляется линия посередине

мне действительно нужна помощь, потому что я нахожусь на ней неделю, и я не могу ее решить

код:

        IDEAL

        MODEL large
    Macro ReadBmp FileName
        mov [Lines],0
        mov [Weight],0



        mov ax,[Y]
        mov [CurrentY],ax

        mov [XScreen],0
        mov [YScreen],0


        mov dx, offset FileName  ;Mov Dx Offset Of File To Read It
        ;call ClearBuff
        call ReadToBuffer       ;Call Proc That Move Values To Buffer
        call ShowBMP

        mov ax,[CurrentY]
        mov [Y],ax
    EndM
    P386
        STACK 256

        RightDown        equ 77
        LeftDown         equ 75
        UpDown           equ 72
        DownDown         equ 80
        ScreenRam        equ 0A000h

        DATASEG
        ErrorMsg         DB 'There Is A Problem To Show The File$'
        Handle           DW ?
        File             DB 'Map.bmp',0
        Index            DD ?
        X                DW 0
        Y                DW 0
        CurrentY         DW 0
        XScreen          DW 0
        YScreen          DW 0
        Weight           DW 0
        Lines            DB 0
        ;SizeFile DD 0 
    SEGMENT BufferBmp para public  ;'DATA'  
            DB 65535 DUP(0)
    ENDS

            CODESEG   

    Start:
            mov ax, @data
            mov ds, ax

            mov ax, BufferBmp
            mov es, ax

            mov ax, 0013h
            int 10h

    Draw:           
            ReadBmp File
    lop:        

            mov ah,00
            int 16h
            cmp ah,RightDown
            je Right
            cmp ah,LeftDown
            je Left
            cmp ah,UpDown
            je Up
            cmp ah,DownDown
            je Down
            cmp ah,1
            je Exit
    jmp lop

    Right:
        add [X],5
    jmp Draw
    Left:
        sub [X],5
    jmp Draw
    Up:
        sub [Y],5
    jmp Draw
    Down:
        add [Y],5
    jmp Draw

    Exit:
            mov ax,04c00h
            int 21h

    Proc ClearBuff near
        mov si,0
        mov al,15
    NoFinish:
        mov [es:si],al
        inc si
        cmp si,65535
        jne NoFinish
    ;-----------------------------Clear Screen-----------------------------;
            mov ax,ScreenRam      
            xor di,di                           
            mov cx,320*200/2                    
            mov al,0d                           
            mov ah,0d                           
            rep stosw                           
    ;-----------------------------Clear Screen-----------------------------;
        ret
    endp
    Proc ReadToBuffer near
    ;--------------------OpenFile Use Handle--------------------;
        mov ah, 3Dh             ;INT 21 Know If Ah == 3dh He Need To Open/Create File
        mov al, 0               ;Read Only
        ;mov dx,offset FileName
        int 21h
        jc  @@Err
        mov [Handle], ax        ;Handle On ax Go To Var
    ;--------------------Copy Lines To Buffer------------------;
    ;--------------------Move Pointer To Check End Of File--------------------;
    ;   mov     ah,  42h                 ;int 21h Know That If AH == 42h He Move Pointer On File
    ;   mov     al,  02                  ;End Of File To Know Size Of A File
    ;   mov     bx, [Handle]             ;BX = file handle
    ;   xor     ecx,ecx                  ;CX:DX = offset from origin of new file position.
    ;   xor     edx,edx                  ;CX:DX = offset from origin of new file position.  
    ;   int     21h                 
    ;   jc      @@Err
    ;   ;Enter The Image Size Into A Variable
    ;   mov     [SizeFile],eax 
    ;   mov     eax,65536
    ;   mul     edx
    ;   add     [SizeFile],eax
    ;   cmp     [SizeFile],0
    ;   je     @@Err
    ;--------------------Move Pointer To Check End Of File--------------------;
    @@Lop:         
    ;--------------------Calculate index By WY+X-------------;
        mov     eax, 1920                ;Eax == 1920(Weight Of Map)
        xor     ebx, ebx                 ;ebx = 0
        mov     bx,  [Y]                 ;Bx == Y   
        mul     ebx                      ;W*Y
        xor     ebx, ebx                 ;Ebx = 0
        add     ax, [X]                  ;WY+X 
    ;--------------------Calculate index By WY+X-------------;
    ;--------------------Flip Image--------------------;
        ;mov    [index],eax              ;index == eax
        ;mov     eax,[SizeFile]          ;eax == All Byte Image 
        ;sub     eax,[index]                 ;Eax - Index
    ;--------------------Flip Image--------------------;

        mov     [index],eax              ;index == eax
        xor     edx, edx                 ;edx = 0
        mov     ebx, 65536               ;ebx = 65536
        div     ebx                      ;Dx = Remains,ax = dose
        mov     ecx,  eax                ;CX = high order word of number of bytes to move
        xor     ebx, ebx                 ;edx = 0
                                        ;CX:DX distance to move file pointer: offset is (CX * 65536) + DX

    ;--------------------Move Pointer To Read Data--------------------;
        mov     ah,  42h                 ;int 21h Know That If AH == 42h He Move Pointer On File
        mov     al,  00                  ;Current Location Plus Offset
        mov     bx, [Handle]             ;BX = file handle
                                        ;CX:DX = offset from origin of new file position. 
        int     21h                 
        jc      @@Err
    ;--------------------Move Pointer To Read Data--------------------;

    ;--------------------Read Data--------------------;

        mov     bx, [Handle]             ;BX = file handle
        mov     dx, [Weight]             ;DS:DX = pointer to read buffer
        pusha     
        push    ds
        mov     ax, BufferBmp
        mov     ds, ax
        mov     cx, 320                 ;CX = number of bytes to read---;320 = Line;
        mov     ah, 3Fh
        int     21H
        pop     ds
        popa
        jc      @@Err           
    ;--------------------Read Data--------------------;
        inc     [Lines]
        inc     [Y]                      ;Add Y To Calculate Position
        add     [Weight], 320            ;Add Weight X
        cmp     [Lines],  200            ;Check End
        jne     @@Lop

        mov     ah, 3Eh                  ;Close File
        mov     bx,[Handle]              ;BX = file handle
        int     21H
        jc      @@Err   
        ret

    @@Err:  
            mov     ax, 3                ; Set text mode
            int     10h
            mov     dx, offset ErrorMsg
            mov     ah, 09h
            int     21h                  ;Print Error
            jmp     Exit
    endp

    Proc ShowBMP near
        mov si,0                     ;Start From The Begining Of Buffer
        mov bx,0                         ;page 0
    @@Horizontal:                        
        mov ah,0Ch                       ;int 10h Know That If AH == 0Ch He Write Graphics Pixel at Coordinate
        mov al, [es:si]                  ;Color
        mov cx,[XScreen]                 ;X
        mov dx,[YScreen]                 ;Y
        int 10h
        inc si                           ;mov to next pixel
        inc [XScreen]                    ;Add X
        cmp [XScreen],320                ;Check End Line
        jne @@Horizontal
        inc [YScreen]                    ;Add Y
        mov [XScreen],0                  ;Start New Line
        cmp [YScreen],200                ;Check End Of Image
        jne @@Horizontal
    ret
    endp



    End Start

Программа, использующая этот образ : https://drive.google.com/file/d/1T8aBZr8mtCUmQL2WKmQfklmEMfaOCklG/view?usp=sharing

1 Ответ

1 голос
/ 03 мая 2020

add ax, [X]

При расчете смещения файла вы не учитываете перенос от добавления X

mov     eax, 1920                ;Eax == 1920(Weight Of Map)
xor     ebx, ebx                 ;ebx = 0
mov     bx,  [Y]                 ;Bx == Y   
mul     ebx                      ;W*Y
xor     ebx, ebx                 ;Ebx = 0
mov     bx, [X]  
add     eax, ebx   <<<< correct addition

Преобразование этого 32-разрядного числа в CX: DX просто:

push eax
pop  dx
pop  cx

Это деление на 65536 было бесполезным.
Теперь вы можете вызывать DOS.function 42h.


Каждый графический файл .BMP начинается с заголовка, который содержит важную информацию об изображении. Для вашего 256-цветного растрового файла это:

  • BITMAPFILEHEADER 14 байт
  • BITMAPINFOHEADER 40 байт
  • COLORTABLE

Затем приходят данные пикселей, которые вам нужны. Вот почему ваш расчет смещения файла должен добавить eax, 14 + 40 + 1024 .

movzx   eax, word [Y]       ; Y position within bitmap
imul    eax, 1920           ; Width of bitmap
movzx   ebx, word [X]       ; X position within bitmap
lea     eax, [eax+ebx+1078] <<<< Plus offset to start of pixel data
push    eax
pop     dx
pop     cx
...