中国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
查看资料  发送邮件  发短消息 网志   编辑帖子  回复  引用回复

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


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



论坛跳转: