用.NET&Java的眼光看汇编语言

假设在.NET平台下要实现像下面这张图的效果,我们可以很简单地用几行代码来实现:
预设10个状态值作为“跑马灯”每一张图片的输入值,加上一个Timer控件设定一个Interval值,在Elapased事件下写输出值的代码并刷新UI。当然,前提是有像8255单片机这样的模拟机与程序通信。
但在汇编下要实现这样的效果可真要费一番功夫。先说一下题目要求:
当开关K1                  合上其余断开时,L1~L8从右到左逐个点亮直到开关状态改变
当开关K1、K2         合上其余断开时,L1~L8从右到左成对逐次点亮直到开关状态改变
当开关K1、K2、K3合上其余断开时,L1~L8从右到左以3个为一组逐次点亮直到开关状态改变
……
开关K1~K8全部合上时停止
这里需要注意的是每种状态下点亮灯的个数,左移的效果可以用ROL指令来现实,过程中还要保存左移后的值,还有当运行时改变开关状态(2个灯增加到3个灯)时灯的效果也要随着改变。
那天计算机硬件实验花了我一下午才把这个搞出来,后来才发现运行时改变开关状态的这个功能有错误,直接把CL的值赋给了AL,又把新开关状态的值给覆盖了。可惜,下课了,没来得及改…
还有,是否有一款模拟8255或其它单片机的软件,以后直接在寝室里做实验得了,实验室可以不去了
------------------------------------------
有时候在想,汇编这么复杂,指令多(难记,不像高级语言的int、string类型好记)、寄存器限制(8b、16、32b)、IP指针常变(POP、PUSH)、现场保护…真多,这些问题不得不关注
大家知道JIT编译器是把中间语言编译成相应处理器指令,而中间语言(*.dll---.NET、*.class---Java)一般有10几K上百K,写个汇编程序一般不到5K,从大小层面上看JIT编译器应该复杂多了。而且用高级语言编写的程序在运行时都不只调用一个*.dll文件,数量上又增加了一个复杂度。况且高级语言对代码安全、堆栈保护、防止缓冲区溢出都有相当高的要求!
能写出像.NET平台这样的JIT确实是个牛人!
做实验时拍下来的 
附:做该汇编实验时的代码,有兴趣的可以瞧瞧,在这不做技术讨论

DATA SEGMENT
        CTRL DB 82H                     ;定义控制字
DATA ENDS
CODE SEGMENT
MAIN PROC FAR
        ASSUME CS:CODE,DS:DATA
START;
        PUSH DS
        MOV AX,0
        PUSH AX
        MOV AX,DATA
        MOV DS,AX
        MOV DX,20BH                  ;8255的控制口地址
        MOV AL,CTRL
        OUT DX,AL

        MOV DX,209H                  ;8255-B口地址,接收开关输入信号
        IN AL,DX
        MOV DX,20AH                 ;8255-C口地址,输出AL值
        OUT DX,AL

        MOV BL,AL                    ;保存开关输入信号,BL为左AL左移后的值         

 MOV CL,AL                           ;CL为执行L1前AL的值
L1:
        MOV DX,209H                 
        IN AL,DX
        CMP AL,01H                   ;逐个与01H、03H…比较
        JZ L2
        CMP AL,03H
        JZ L2
        CMP AL,07H
        JZ L2
        CMP AL,0FH
        JZ L2
        CMP AL,1FH
        JZ L2
        CMP AL,3FH
        JZ L2
        CMP AL,7FH
        JZ L2
        CMP AL,0FFH
        END1:RET                      ;当输入为0FFH(1111 1111B)或其它值时退出
L2:                                           ;控制二极管循环点亮
        MOV AL,BL                   ;把上次左移后的AL值(存放在BL)送到AL
        ROL AL,1                       ;左移AL 1位
        MOV DX,20AH
        OUT DX,AL                   ;输出移位后的值,效果就是二极管向左点亮了
        MOV BL,AL
        MOV AL,CL
        PUSH BX                       ;把BX、CX值压栈,保存BL、CL的值
        PUSH CX
        MOV BX,0FFFFH         ;外循环次数
LO:                                         ;外循环
        MOV CX,0FFFFH
LI:                                          ;内循环
        NOP
        NOP
        NOP
        LOOP LI
        SUB BX,1
        JNZ LO
        POP CX                       ;弹出CX值
        POP BX                       ;弹出BX值
        JMP L1
        RET
MAIN ENDP
CODE ENDS
        END START

posted @ 2006-11-19 21:32  Doho  阅读(439)  评论(0编辑  收藏  举报