中国DOS联盟论坛

中国DOS联盟

-- 联合DOS 推动DOS 发展DOS --

联盟域名:www.cn-dos.net  论坛域名:www.cn-dos.net/forum
DOS,代表着自由开放与发展,我们努力起来,学习FreeDOS和Linux的自由开放与GNU精神,共同创造和发展美好的自由与GNU GPL世界吧!

游客:  注册 | 登录 | 命令行 | 搜索 | 上传 | 帮助 »
中国DOS联盟论坛 » DOS开发编程 & 发展交流 (开发室) » 给宏汇编语言加入高级语言特性
作者:
标题: 给宏汇编语言加入高级语言特性 上一主题 | 下一主题
本是
银牌会员





积分 2201
发帖 789
注册 2005-1-27
状态 离线
『楼 主』:  给宏汇编语言加入高级语言特性

给宏汇编语言加入高级语言特性: 程序控制IF/WHILE/UNTIL结构块 与 带参数表的PUSH/POP/CALL语句 汇编语言给人的感觉是充分的代码自由VS无限的责任,代码紧凑、运行速 度快,但缺少高级控制结构,子程序调用与现场处理的参数表传递冗长繁琐、 不直观,亲合力差。其实,通过宏汇编、重复汇编、数据结构、数据记录等高 级技术,选择一个功能比较完善的汇编例程库,完全可以实现汇编语言的高级 化界面。下面谈谈结构宏与栈宏。 ===<<< 程序控制结构块 >>>=== ┌────────────────────────┐ │ 程序控制能力增强,设计时有更多精力用于功能处理 │ │ 源程序中行标减少、按层嵌套,逻辑清晰、读写方便 │ └────────────────────────┘ [原有功能] 基于Davidson Corry(4610 SW Lander,Seattle,WA 98116,(206) 935-0244) 的SIT.INC,可称为“坐享”宏汇编程序控制结构块,实现高级语言程序控制结 构,一分支_IF.._ELSE.._ELSEIF.._ENDIF,二循环_WHILE..和.._UNTIL,甚至 有类似C语言的 _BREAK、_CoNTiNUe语句。借助这些程序控制结构块,汇编语言 源程序中可以大大减少跳转与循环的目标行标号的使用量,程序控制能力增强, 让程序员集中精力处理功能问题,方便自上而下逐步求精的结构化程序设计实践, 象高级语言一样地按层次缩进嵌套,逻辑清晰,读写方便。 原宏名及变量名起始符_可避免与MASM6.x内嵌宏名起始符.冲突,予以保留; 未设计的FOR循环、多分支CASE可通过已有循环语句和单分支_IF模拟实现。 [我的改进] MS-DOS6.xx源码中 STRUC.INC对长跳转的处理巧妙自动测试跳转长度和前后 跳转,TASM编译器通过加入后置近距长跳转作为超长距离的长循环的LOOP目标巧 妙实现对长循环的处理,同时借用微软的长跳转判断,如此就增加了对>128字节 的长跳转循环的支持,且无需用户动手!当然,J和JN指令需重新定义为JMP xxx。 其它的优化还有: 改JNNcc/JNNNcc指令名宏定义法为EQU法,大大缩短了宏代码长度; 增加同义宏名_CONTINUE/_CONTICX/_UNTILCX/_ENDW,兼容MASM6.xx内嵌.指令; 增加JNCXZ/JNNNcc/JNN/JNNN宏定义,使跳转条件更完备,编译得以正常完成; 增加循环语句_WNTIL/_UHILE,使"当"、"到"有更多搭配,适合复杂的条件判断。 [程序控制结构的实质]--利于理解宏的参数 一言以蔽之,程序控制结构的实质就是:程序控制=跳转与循环的控制 从程序设计的角度看,程序的流程控制,就是跳转与循环目标(即行标)的 控制,实质是跳转与循环的操作引起标志寄存器的变化,而控制跳转与循环的 走向。 从非结化程序的结构化转换的角度看,当指令影响的寄存器标志成为跳转 (jmp/jcxz/j???)与循环(loop[n][e|z])的条件时,实施结构化转换。 [程序控制结构的类型及举例]--见“********************”后 ===<<< 堆栈传参的压弹调用 >>>=== ┌────────────────────────┐ │ 堆栈传参,同行同序,方便汇编处理现场、调用程序 │ └────────────────────────┘ 由于汇编语言对PUSH/POP/CALL的规定,利用堆栈传递参数的程序中会见到如下 代码浪费源程序空间(指视觉上),子程序调用与参数表分离又不能象高级语言 一样直观清晰。 push bx push cx push dx push si ;... pop si pop dx pop cx pop bx push ax ; P5 push 16h ; P4 push 3Dh ; P3 push 0B4h ; P2 push 0F0h ; P1 call sub_035C push ax ; P3 push word ptr [bp+P5] ; P2 push word ptr [bp+LOCAL_2] ; P1 call sub_048B 现在有了_PUSH/_POP/P0P/_CALL,你完全可以象高级语言一样地使用汇编语言! 上面的三段可以改成: _push bx,cx,dx,si ;;压栈序(顺:末后) ;... _pop bx,cx,dx,si ;;弹出序(反:末先) ; putpixel P1 x P2 y P3 c _call sub_048B,<[bp+LOCAL_2]>,<[bp+P5]>,ax ; line x0 y0 x1 y1 c _call sub_035C,0F0h,0B4h,3Dh,16h,ax 注意: 1) _PUSH/_POP成对使用,参数表同序,方便复制粘贴。如要顺序弹出,用_P0P: _p0p si,dx,cx,bx ;;弹出序(顺:末后) 2)“_CALL 函数名,参数表”格式中参数压入序反:末参先入--变换时不要搞错! 参数可以是:直接数/寄存器/全局/局部变量(含offset loc_1)/主程序参数 这样的栈序方便理解/修改,编程效率高。 ***************************************************************************** [程序控制结构的类型及举例] ============================ [程序控制结构块的类型] ------------------------ 判断: ~~~~~~ _IF ; _ELSE ; _ELSEIF ; _ENDIF _ELSEIF及_ELSE为另一情形,_IF结构为高级语言中所必备! 循环: ~~~~~~ 0. 死循环(必须用_BREAK跳出!) 无测类 _REPEAT ; _ENDW 1. “当”型(“当”条件成立,则执行循环体,否则执行循环外的语句) 前测类(最常用) _WHILE ; _ENDW 后测类 _REPEAT ; _WHILE 2. “到”型(循环一直“到”条件成立即停止循环) 前测类 _WNTIL ; _ENDW 后测类(最常用) _REPEAT ; _UNTIL 3. 混合型 双测类 _WHILE ; _UHILE _WNTIL ; _UNTIL _WHILE ; _UNTIL _WNTIL ; _UHILE 4. LOOP型 _REPEAT (最常用) ; _UNTILCX _WHILE ; _UNTILCX _WNTIL ; _UNTILCX UNTILCX同UNTIL,但加上判断CX是否为0 (OR的关系,即条件为真或CX为0) 配合上述循环指令运用 _BREAK 可中止循环 _CONTINUE 可跳至循环开头 _CONTICX 可跳至循环开头(用于_UNTILCX循环中) 可在其后加上测试语句op,条件cnd(_CONTICX只加cnd),条件成立才动作 上述指令中_ELSE、_ENDIF不需要任何参数, _UNTILCX、_CONTICX只要一个条件参数(=LOOPcc之cc), 其余需要测试语句(cmp等)和条件(=Jcc之cc)两个参数。 循环条件参数LOOPcc之cc: Z/E NZ/NE 空白 影响寄存器标志的测试语句op列表: SAHF POPF SHL/R RCL/R SAL/R ROL/R STC CLC CMC NOT AND OR XOR TEST NEG CMP[S] SCAS ADD SUB ADC SBB INC DEC REP CALL 跳转条件参数Jcc之cc: [[N]A/AE/B/BE/C/CXZ/E/G/GE/L/LE/O/P/PE/PO/S/Z] [程序控制结构块的举例]--从非结构化程序段的结构化角度 ====================================================== ;_IF结构以CMP举例如下: ;----------------------- ;CMP cmp ax,word ptr es:[1] _IF <cmp ax,word ptr es:[1]>,e jne _02E8 ;... ;... _02E8: _ENDIF ;CMP放在_IF块前 cmp ax,word ptr es:[1] cmp ax,word ptr es:[1] jne _02E8 _IF ,e ;... ;... _02E8: _ENDIF ;CMP与J...之间有其它语句 cmp ax,word ptr es:[1] cmp ax,word ptr es:[1] mov dx,offset _0888 mov dx,offset _0888 jne _02E8 _IF ,e ;... ;... _02E8: _ENDIF ;分支_ELSE cmp byte ptr ds:[0080h],0 _IF <cmp byte ptr ds:[0080h],0>,ne je _0129 ;... ;... jmp short _0133 _0129: _ELSE ;... ;... _0133: _ENDIF ;多分支_ELSEIF (也就是SWITCH...CASE) cmp _0142,3 _IF <cmp _0142,3>,e jne _037F ;... ;... jmp short _0395 _037F: _ELSEIF <cmp _0142,4>,e cmp _0142,4 jne _038B ;... ;... jmp short _0395 _038B: _ELSEIF <cmp _0142,5>,e cmp _0142,5 jne _0395 ;... ;... _0395: _ENDIF ;嵌套_IF cmp al,'a' _IF <cmp al,'a'>,ae jb _0484 cmp al,'z' _IF <cmp al,'z'>,be ja _0484 ;... ;... _0484: _ENDIF _ENDIF ;循环结构举例如下: ;------------------- ;WHILE型(CMP) _05D4: _WHILE <cmp byte ptr [di],0>,ne cmp byte ptr [di],0 je _05DC inc di inc di jmp short _05D4 _ENDW _05DC: ;CMP实现的BREAK=C的BREAK或BASIC的EXIT FOR/DO/LOOP _041D: _WHILE <cmp byte ptr [si],0>,a cmp byte ptr [si],0 jbe _042A cmp byte ptr [si],' ' _BREAK <cmp byte ptr [si],' '>,a ja _042A inc si inc si jmp short _041D _ENDW _042A: ;BREAK特例 repe cmpsb repe cmpsb ;... ;... jz _0590 _BREAK ,e ;以UNTILCX回跳 mov si,[0081h] mov si,[0081h] jcxz _027B _IF ,ncxz _0270: .REPEAT ;... ;... inc si inc si loop _0270 .UNTILCX _027B: _ENDIF ;以CONTINUE中途回跳 _0296: _REPEAT ;... ;... test ax,ax _BREAK <test ax,ax>,z jz _02C6        mov si,dx mov si,dx cmp byte ptr [si],1Ah _BREAK <cmp byte ptr [si],1Ah>,e je _02C6           cmp byte ptr [si],0Dh _IF <cmp byte ptr [si],0Dh>,e jne _02C3 cmp dx,5E7h _CONTINUE <cmp dx,5E7h>,e je _0296 mov byte ptr [si],0 mov byte ptr [si],0 jmp short _02C6 _BREAK _02C3: _ENDIF inc dx inc dx jmp short _0296 _ENDW _02C6: ;;非结构化改造为结构化 ;初步结构化 _057E: _REPEAT cmp byte ptr [di],0 cmp byte ptr [di],0 ;;非结构化 je _059B je _059B ;;语句 ;... ;... inc di inc di jmp short _057E _ENDW _0590: _REPEAT ;... ;... jmp short _0590 _ENDW _059B: _059B: ;结构化方法1:重复判断 ;结构化方法2:增设标志 _REPEAT _REPEAT _BREAK <cmp byte ptr [di],0>,e _IF <cmp byte ptr [di],0>,e mov $_flag,-1 _ELSE mov $_flag,0 ;... ;... inc di inc di _ENDIF _ENDW _ENDW _IF <cmp byte ptr [di],0>,ne _IF <cmp $_flag,0>,e _REPEAT _REPEAT ;... ;... _ENDW _ENDW _ENDIF _ENDIF ;;FOR型循环的模拟(有确定的初值,终值,步长) mov bx,start ;初值(赋值方法多样,甚至不明显出现) _REPEAT _BREAK <cmp bx,stop>,g ;终值\ ;... ; \ ;... ;循环体-->三种语句的相对位置非常灵活 ;... ; / add bx,step ;步长/ _ENDW ============= 注:附件内sitmac.txt、sitmac.inc、sitdial.asm分别是说明文件、宏定义文件、应用实例(对话框窗口)。 [ Last edited by 本是 on 2007-3-5 at 04:02 AM ]


附件 1: Sitmac.rar (2007-3-5 04:02, 10.74 K, 下载附件所需积分 1 点 ,下载次数: 20)


my major is english----my love is dos----my teacher is the buddha----my friends--how about U
2007-3-5 03:49
查看资料  发送邮件  发短消息  网志   编辑帖子  回复  引用回复
happyman06
初级用户




积分 52
发帖 19
注册 2006-9-2
状态 离线
『第 2 楼』:  

超级经典! 一定要加分! 严重支持 本是大哥!


2007-3-5 12:19
查看资料  发送邮件  发短消息  网志   编辑帖子  回复  引用回复
本是
银牌会员





积分 2201
发帖 789
注册 2005-1-27
状态 离线
『第 3 楼』:  

1楼修正错误: ;以UNTILCX回跳 mov si,[0081h] mov si,[0081h] jcxz _027B _IF ,ncxz _0270: .REPEAT ;... ;... inc si inc si loop _0270 .UNTILCX _027B: _ENDIF 红色标出的行首的.就改为_




my major is english----my love is dos----my teacher is the buddha----my friends--how about U
2007-3-5 13:25
查看资料  发送邮件  发短消息  网志   编辑帖子  回复  引用回复
netwinxp
高级用户





积分 741
发帖 366
注册 2007-7-25
状态 离线
『第 4 楼』:  

MASM6.1及以上版本本身就支持: 1).IF——.ELSE——.ENDIF 2).WHILE——.ENDW 3).WHILE——.BREAK——.ENDW 4).REPEAT——.UNTIL 这些结构化语句 当子程序用 子程序名 PROTO FAR C 参数1[,参数2....]声明时,用INVOKE调用为C语言风格参数传递;子程序名 PROTO FAR PASCAL 参数1[,参数2....]声明,用INVOKE调用为PASCAL语言风格参数传递。


2007-7-26 00:43
查看资料  发短消息  网志   编辑帖子  回复  引用回复
不点
银牌会员

不甘寂寞的人


积分 2491
发帖 1115
注册 2003-9-24
状态 离线
『第 5 楼』:  

我很支持本是的做法。我记得 smart boot manager 里面的 nasm 汇编,其中的一些模块就是以结构化的方式来实现的。因此,汇编语言结构化的工作在很早就开展了。不过我认为,这块工作还没有结束,没有达到成熟,因此仍然需要编程语言设计者继续工作。 我希望本是兄做以下两个工作(这也是我想做的,但精力不够只好放弃): 1. 开发一个开放源码的 MS-DOS 替代品。 2. 开发一个编程语言,这个编程语言具有汇编语言的全部功能,又能像 c,c++,以及 UNIX 的 shell 那样。也就是说,从低级高级再到超高级,都融合在一起了,而且既可以解释执行,也可以编译执行。




因为我们亲手创建,这个世界更加美丽。
2007-7-26 09:03
查看资料  发送邮件  发短消息  网志   编辑帖子  回复  引用回复

请注意:您目前尚未注册或登录,请您注册登录以使用论坛的各项功能,例如发表和回复帖子等。


可打印版本 | 推荐给朋友 | 订阅主题 | 收藏主题



论坛跳转: