![]() |
#2
Valenciax2016-06-16 10:00
代码:
![]() read_buf equ 0C0h paramater_L equ 64 ; -------------MASM Marco definition start --------------------- @GetCur MACRO page ;读取光标位置 IFNB <page> mov bh,page ELSE xor bh,bh ENDIF mov ah,03h int 10h ENDM @SetCurPos MACRO column,row,page ;设定光标位置 IFNB <column> mov dl,column ENDIF IFNB <row> mov dh,row ENDIF IFNB <page> mov bh,page ELSE xor bh,bh ENDIF mov ah,02h int 10h ENDM @GetChAtr MACRO page ;读取光标属性 IFNB <page> mov bh,page ELSE sub bh,bh ENDIF mov ah,08h int 10h ENDM @SetCurSz MACRO first,last ;设定光标大小 mov ch,first mov cl,last mov ah,01h int 10h ENDM @PutChAtr MACRO char,atrib,page,repeat ;显示颜色字节 IFNB <char> mov al,char ENDIF IFNB <atrib> mov bl,atrib ENDIF IFNB <page> mov bh,page ELSE xor bh,bh ENDIF IFNB <repeat> mov cx,repeat ELSE mov cx,1 ENDIF mov ah,09h int 10h ENDM ; -------------MASM Marco definition end --------------------- COD segment assume cs:cod, ds:cod,es:cod org 100h start: jmp begin msg_L db 0 first_pos dw 0 exit_flag db 0 attrib db 0 column dw ? row dw ? press dw 0 cur_size dw 0 cur_pos dw 0 msg_x db 0 msg_y db 0 errmsg db "No mouse installed !",10,13,'$' help db 'Usage : Pickme [String]',10,13,'$' begin: mov ax,0 ;check mouse install int 33h ;mouse int cmp ax,0ffffh ;installed jz go ;yes, continue mov dx,offset errmsg quit: mov ah,09h int 21h jmp exitX ;quit to dos go: mov si,80h ;指向psp参数输入区,即紧贴程式后的输入 lodsb or al,al jnz go2 go1: mov dx,offset help jmp quit go2: cmp al,paramater_L ja go1 mov cl,al mov msg_L,al xor ch,ch mov bl,cl xor bh,bh mov byte ptr [bx+si],0 ;0 overwrite 0dh xor bp,bp go3: lodsb cmp al,' ' jnz go4 inc bp loop go3 go4: dec si dec si mov first_pos,si mov byte ptr [si],' ' mov al,msg_L xor ah,ah sub ax,bp inc ax mov msg_L,al @GetCur ;get cursor mov cur_size,cx ;store cursor size mov cur_pos,dx dec dh mov msg_y,dh mov di,0c0h mov cx,paramater_L mov dl,0 go10: @setCurPos dl,dh @GetChAtr stosb inc dl loop go10 mov cx,paramater_L xor bp,bp go11: push cx mov cl,msg_L mov ch,0 mov di,first_pos mov si,0c0h add si,bp repe cmpsb ;compare ds:si and es:di jz go12 pop cx inc bp loop go11 mov word ptr msg_x,0 jmp go13 go12: pop cx sub cx,paramater_L neg cx mov msg_x,cl go13: @SetCurSz 30h,31h ;hidden cursor @SetCurPos msg_x,msg_y call read_msg mov si,first_pos mov attrib,70h ;反白 call dispstr mov ax,1 ;display mouse cursor int 33h mov ax,8 mov cx,0 mov dx,23*8 ;max mouse vertial move int 33h restart: mov ah,06h ;keyboard mov dl,0ffh ;input mode int 21h jz j5 cmp al,1bh ;press <esc> jnz j5 mov exit_flag,1 jmp draw j5: mov ax,3 ;get mouse status int 33h shr dx,1 ;dx / 8 + 1 shr dx,1 shr dx,1 mov row,dx ;取列 shr cx,1 ;cx / 8 + 1 shr cx,1 shr cx,1 mov column,cx ;取行 cmp bx,1 jz j10 mov press,0 j10: cmp press,1 jnz j20 cmp cl,msg_x jnz draw cmp dl,msg_y jz restart jmp draw j20: cmp dl,msg_y jnz restart cmp cl,msg_x jb restart mov al,msg_x add al,msg_L cmp cl,al ja restart cmp bx,1 jnz restart mov press,1 draw: @SetCurPos msg_x,msg_y mov si,read_buf mov attrib,07h call dispStr cmp exit_flag,1 jz exit mov ax,column mov msg_x,al mov ax,row mov msg_y,al @SetCurPos msg_x,msg_y call read_msg mov si,first_pos mov attrib,70h call dispstr jmp restart exit: mov ax,2 ;hide mouse cursor int 33h mov cx,cur_size @SetCurSz ch,cl mov dx,cur_pos dec dh @SetCurPos dl,dh exitX: mov ah,4ch ;end program int 21h ;---------------------------------------------------------------------------------- read_msg: push ax push bx push cx push dx push di push word ptr msg_x mov cl,msg_L xor ch,ch mov di,read_buf ;psp 0C0h read1: push cx @GetChAtr stosb ;store to 0c0h inc msg_x @SetCurPos msg_x,msg_y pop cx loop read1 mov al,0 stosb pop word ptr msg_x @SetCurPos msg_x,msg_y pop di pop dx pop cx pop bx pop ax ret ;---------------------------------------------------------------------------------- DispStr: @GetCur ds1: lodsb or al,al jz ds_exit @PutChAtr al,attrib inc dl @SetCurPos dl,dh jmp ds1 ds_exit: ret ;---------------------------------------------------------------------------------- cod ends end start [此贴子已经被作者于2016-6-16 17:48编辑过] |
这是一个滑鼠操作的简单程式,但不是win32的视窗程式,是dos的16bit。
许多大学的汇编教材,还停留在三十年前的dos年代,地址还是段:移偏,
永远是一个黑框,永远是2、10、16进制转换,永远是印几个烂字符,
能够改变颜色已经进阶级别了。
就我来看,学汇编是学它的灵活性,学它对地址的运用,只要你理解CPU
是如何定址,如何间接定址,如何间接再间接定址,那么C,C++常为人诟病的
指针就会不说自明。
鼠标操作在win32是挺简单的,只要在消息串列里拿到
WM_MOUSEMOVE 鼠标移动,将参数lParam变换为x,y坐标就知道鼠标的位置
WM_RBUTTONDOWN ;右键按下
WM_LBUTTONDOWN ;左键按下
完事了,根据程式要和鼠标位置做事。
可是,大家忘了DOS里其实也可以操作鼠标,我猜,许多学了一整季汇编的学生,
还不知道有鼠标的存在。翻了几页论坛的贴,似乎找不到一个操作鼠标的程式。
好吧,我来抛砖引玉(很耳熟啊),发一个本人初学汇编时的一个练习。
这程式利用了一些MASM定义的宏,主要是BIOS对光标的操作。
INT 33H是DOS的标准滑鼠操作中断
ax=0,检查安装与否
ax=1,显示滑鼠指标
ax=2,隐藏滑鼠指标
ax=3,取得滑鼠位置
编译方法:
copy代码存成ANSI标准文字档格式,档名任意,可叫作pickme.asm
本程式是com格式
masm 5.x :
masm pickme.asm
link pickme.obj pickme.exe
exe2bin pickme.exe pickme.com
del pickme.exe
masm 6.x
ML /AT pickme.asm
运行程式:
在windows/dos下,或dosbox或虚拟dos,或纯dos下(需安装滑鼠驱动)
键入pickme [String]
[String] 可以是任意字符串,比如hello world, i am a boy, you are a girl 之类
然后:
1把鼠标移到字符串的上方,按左键不放
2.拖拉到任意位置,松开左键丢下字符串
3. 重复1,直到你玩厌了,按ESC离开
代码很短,写了简短解释,因为那时初学,程式写得很烂,没什么高探技术。
程式也没多大用途,只是一个汇编练习,当它是个玩意就不会闷。
只有本站会员才能查看附件,请 登录
二楼发代码。
[此贴子已经被作者于2016-6-16 10:06编辑过]