![]() |
中国DOS联盟-- 联合DOS 推动DOS 发展DOS --联盟域名:www.cn-dos.net 论坛域名:www.cn-dos.net/forum |
| 游客 | 登录 | 注册 | 会员 | 搜索 | 中国DOS联盟 |
|
中国DOS联盟论坛 现在时间是 2026-10-31 20:41 |
共 47,815 主题排行 / 349,930 发帖 / 今日 0 篇 / 48,290 会员排行 |
| DOS开发编程 & 发展交流 (开发室) » 给宏汇编语言加入高级语言特性 |
| 可打印版本 1,652 / 4 |
| 第1楼 本是 | 发表于 2007-03-05 03:49 |
| 银牌会员 发帖 790 积分 2,227 | |
|
给宏汇编语言加入高级语言特性 给宏汇编语言加入高级语言特性:
程序控制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)的条件时,实施结构化转换。 --见“********************”后 ===<<< 堆栈传参的压弹调用 >>>=== ┌────────────────────────┐ │ 堆栈传参,同行同序,方便汇编处理现场、调用程序 │ └────────────────────────┘ 由于汇编语言对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 ; P2 push word ptr ; 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,<>,<>,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 ADD SUB ADC SBB INC DEC REP CALL 跳转条件参数Jcc之cc: 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: _IF <cmp ax,word ptr es:>,e jne _02E8 ;... ;... _02E8: _ENDIF ;CMP放在_IF块前 cmp ax,word ptr es: cmp ax,word ptr es: jne _02E8 _IF ,e ;... ;... _02E8: _ENDIF ;CMP与J...之间有其它语句 cmp ax,word ptr es: cmp ax,word ptr es: mov dx,offset _0888 mov dx,offset _0888 jne _02E8 _IF ,e ;... ;... _02E8: _ENDIF ;分支_ELSE cmp byte ptr ds:,0 _IF <cmp byte ptr ds:,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 ,0>,ne cmp byte ptr ,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 ,0>,a cmp byte ptr ,0 jbe _042A cmp byte ptr ,' ' _BREAK <cmp byte ptr ,' '>,a ja _042A inc si inc si jmp short _041D _ENDW _042A: ;BREAK特例 repe cmpsb repe cmpsb ;... ;... jz _0590 _BREAK ,e ;以UNTILCX回跳 mov si, mov si, 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 ,1Ah _BREAK <cmp byte ptr ,1Ah>,e je _02C6 cmp byte ptr ,0Dh _IF <cmp byte ptr ,0Dh>,e jne _02C3 cmp dx,5E7h _CONTINUE <cmp dx,5E7h>,e je _0296 mov byte ptr ,0 mov byte ptr ,0 jmp short _02C6 _BREAK _02C3: _ENDIF inc dx inc dx jmp short _0296 _ENDW _02C6: ;;非结构化改造为结构化 ;初步结构化 _057E: _REPEAT cmp byte ptr ,0 cmp byte ptr ,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 ,0>,e _IF <cmp byte ptr ,0>,e mov $_flag,-1 _ELSE mov $_flag,0 ;... ;... inc di inc di _ENDIF _ENDW _ENDW _IF <cmp byte ptr ,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 ] 附件 Sitmac.rar (10.74 KiB) |
|
| 第2楼 happyman06 | 发表于 2007-03-05 12:19 |
| 初级用户 发帖 19 积分 52 | |
|
超级经典! 一定要加分! 严重支持 本是大哥!
|
|
| 第3楼 本是 | 发表于 2007-03-05 13:25 |
| 银牌会员 发帖 790 积分 2,227 | |
|
1楼修正错误:
;以UNTILCX回跳 mov si, mov si, jcxz _027B _IF ,ncxz _0270: .REPEAT ;... ;... inc si inc si loop _0270 .UNTILCX _027B: _ENDIF 红色标出的行首的.就改为_! |
|
| 第4楼 netwinxp | 发表于 2007-07-26 00:43 |
| 高级用户 发帖 366 积分 741 | |
|
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语言风格参数传递。 |
|
| 第5楼 不点 | 发表于 2007-07-26 09:03 |
| 银牌会员 发帖 1,115 积分 2,491 | |
|
我很支持本是的做法。我记得 smart boot manager 里面的 nasm 汇编,其中的一些模块就是以结构化的方式来实现的。因此,汇编语言结构化的工作在很早就开展了。不过我认为,这块工作还没有结束,没有达到成熟,因此仍然需要编程语言设计者继续工作。
我希望本是兄做以下两个工作(这也是我想做的,但精力不够只好放弃): 1. 开发一个开放源码的 MS-DOS 替代品。 2. 开发一个编程语言,这个编程语言具有汇编语言的全部功能,又能像 c,c++,以及 UNIX 的 shell 那样。也就是说,从低级到高级再到超高级,都融合在一起了,而且既可以解释执行,也可以编译执行。 |
|
|
[ 联系联盟系统管理团队 -
中国DOS联盟 -
标准版 ] Sponsored by ifanr Inc | © 2001–2023 |