我没明白这个示例程序集有啥问题
Posted
技术标签:
【中文标题】我没明白这个示例程序集有啥问题【英文标题】:I Didn't Get Whats wrong with this exemple Assembly我没明白这个示例程序集有什么问题 【发布时间】:2020-05-03 18:16:36 【问题描述】:我做了一个滚动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
【问题讨论】:
您的 ShowBMP 代码似乎假定图像为 320x200,但我从该链接下载的文件是 1920x600? BMP 将其尺寸存储在文件中。为什么不读呢?然后你可以从那里倒数,当你达到零时退出。 我想在这方面为您提供帮助,但您不喜欢我对您的previous question 关于 PCX 的回答吗? 哦,我没看到评论... 无论如何我该如何解决我的问题? :) 尺寸存储在下面 Sep 提到的 BITMAPINFOHEADER 中。 【参考方案1】:添加斧头,[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 色位图文件,这些是:
一个 14 字节的 BITMAPFILEHEADER 一个 40 字节的 BITMAPINFOHEADER 1024 字节可着色然后是您需要的像素数据。这就是为什么你的文件偏移量的计算应该添加 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
【讨论】:
你真的很天才,但是当x,y = 0时,它仍然从图像中间开始,为什么?我还是不明白为什么 x 有一个进位,最大的 x 是 320 @Gad 来自add ax, [X]
的进位不仅取决于X 中的值。 AX
中的内容使加法溢出!
@Gad 非常感谢。我就是喜欢那颗小小的心。以上是关于我没明白这个示例程序集有啥问题的主要内容,如果未能解决你的问题,请参考以下文章
批处理、重复和随机播放对 TensorFlow 数据集有啥作用?
k-means聚类算法python实现,导入的数据集有啥要求