DATAS SEGMENTscrmm DB 100 DUP(?);主菜单名menu1 DB'FILE'menu2 DB'Edit'menu3 DB'RUN'menu4 DB'TOOL'menu5 DB'QUIT';主菜单File下子菜单名submenu11 DB'New'submenu12 DB'Open'submenu13 DB'Save';主菜单Edit下子菜单名submenu21 DB'Cut'submenu22 DB'Past'submenu23 DB'Copy';主菜单Run下子菜单名submenu31 DB'Run'submenu32 DB'Go to'submenu33 DB'Step';主菜单Debug下子菜单名submenu41 DB'Call'submenu42 DB'Find'submenu43 DB'Source';主菜单Help下子菜单名submenu51 DB'About'submenu52 DB'Web'submenu53 DB'Exit';窗口信息msg1 DB'Please press Alt+F,Alt+E,Alt+R,Alt+T,Alt+Q or ',19h,' to open the submenu.'msg2 DB'Please press Enter (',11h,0c4h,0d9h,') to open/close the submenu.' msg3 DB'Please press ',1bh,' or ',1ah,' to select the menu.'msg4 DB'Please press ',18h,' or ',19h,' to select the submenu.';msg7 DB ' ';退出信息'over DB'Thank you for uesing,author by Jianhua';其他信息escape DB'Press ESC to exit.'text1 DB'This is a menu program made with assemble.' sub11 DB'Select New'sub12 DB'Select Open'sub13 DB'Select Save'sub21 DB'Select Cut'sub22 DB'Select Past'sub23 DB'Select Copy'sub31 DB'Select Run'sub32 DB'Select Go to'sub33 DB'Select Step'sub41 DB'Select Call'sub42 DB'Select Find'sub43 DB'Select Source'sub51 DB'Select About'sub52 DB'Select Web'sub53 DB'Select Exit';-------------------------num DB 1 ;主菜单序列号subnum DB?;子菜单序列号subshow DB 0 ;为0时子菜单未显示index DB?;主菜单长度;--------------------------------DATAS ENDS;设置光标位置,显示在0页的(top,left)位置pos MACRO top,leftMOV AH,02hMOV BH,0 ;页号MOV DH,topMOV DL,left ;位置INT 10hENDM;修改菜单属性changemenu MACRO top,left,WIDTH,attrLOCAL chgMOV DL,leftchg:pos top,DL ;置光标位置MOV BH,0 ;页号MOV AH,08h ;读光标位置的属性,AH=属性,AL=字符INT 10hMOV BL,attr ;设置属性MOV CX,1 ;字符重复次数MOV AH,09h ;在光标位置显示字符及设置其属性INT 10hINC DLMOV DH,leftADD DH,WIDTHCMP DL,DH ;设置的循环次数控制JNE chgpos top,leftENDM;绘制窗口drawwindow MACRO attr,top,left,bottom,rightPUSH AXPUSH BXPUSH CXPUSH DXMOV AH,06h ;屏幕初始化MOV AL,0 ;全屏为空白MOV BH,attr ;卷入行属性MOV CH,topMOV CL,left ;左上角坐标MOV DH,bottomMOV DL,right;右下角坐标INT 10hPOP DXPOP CXPOP BXPOP AXENDM;绘制窗口上下边框windowtandb MACRO l,m,r,top,left,WIDTH,attrpos top,left ;置光标位置outputchar l,attr,1 ;输出字符,画左上折角pos top,left+1 ;置光标位置outputchar m,attr,WIDTH-2;输出字符,画上边框pos top,left+WIDTH-1 ;置光标位置outputchar r,attr,1 ;输出字符,画右上折角ENDM;绘制窗口左右边框windowlandr MACRO char,top,left,WIDTH,attr pos top,left ;置光标位置outputchar char,attr,1 ;输出字符,画左边框pos top,left+WIDTH-1 ;置光标位置outputchar char,attr,1 ;输出字符,画右边框ENDM;输出outputchar MACRO char,attr,numPUSH AXMOV BH,0 ;页号MOV AH,09hMOV AL,char ;字符MOV BL,attr ;属性MOV CX,num ;重复次数INT 10hPOP AXENDM;输出串outputstr MACRO str,num,top,left,attrPUSH AXPUSH BXPUSH BPPUSH CXPUSH DXMOV AH,13hLEA BP,str ;字串地址送ES:BPMOV CX,num ;长度MOV DH,topMOV DL,left ;位置坐标MOV BH,0 ;页号MOV AL,0 ;写方式MOV BL,attr ;属性INT 10hPOP DXPOP CXPOP BPPOP BXPOP AXENDM;绘制子菜单submenu MACRO left,menu1,num1,menu2,num2,menu3,num3,WIDTH LOCAL menudrawwindow 70h,1,left,5,left+WIDTH ;画子菜单窗口windowtandb 0dah,0c4h,0bfh,1,left,WIDTH+1,70h ;画子菜单上边筐MOV AL,2menu:windowlandr 0b3h,AL,left,WIDTH+1,70h ;画子菜单左右边筐INC ALCMP AL,5JNE menuwindowtandb 0c0h,0c4h,0d9h,5,left,WIDTH+1,70h ;画子菜单下边筐outputstr menu1,num1,2,left+2,0fh ;(2,left+2)显示子菜单1changemenu 2,left+1,8,0fhoutputstr menu2,num2,3,left+2,70h ;(3,left+2)显示子菜单2 changemenu 3,left+2,1,74houtputstr menu3,num3,4,left+2,70h ;(4,left+2)显示子菜单3 changemenu 4,left+2,1,74hENDM;读取屏幕内容readscr MACRO left,memoryLOCAL readSUB AX,AXMOV SI,AXread:ADD AH,leftINC ALINC SIMOV CH,AHpos AL,CH ;置光标位置MOV AH,08h ;读光标位置字符和属性,AH=字符,AL=属性MOV BH,0 ;页号INT 10hMOV memory[SI],AL ;属性保存MOV memory[SI+50],AH;字符保存MOV AX,SIMOV BL,10DIV BLCMP SI,50JNE readENDM;写入屏幕writescr MACRO left,memoryLOCAL writeSUB AX,AXMOV SI,AXwrite:ADD AH,leftINC ALINC SIMOV CH,AHpos AL,CH ;置光标位置MOV AL,memory[SI] ;属性送ALMOV AH,memory[SI+50];字符送AHMOV DL,ALMOV DH,AHoutputchar DL,DH,1 ;输出MOV AX,SIMOV BL,10DIV BLCMP SI,50JNE writeENDM;设置光标属性showcur MACRO showPUSH AXPUSH CXMOV AH,1MOV CH,show ;光标起始行设置MOV CL,0 ;光标结束行设置INT 10hPOP CXPOP AXENDMSTACKS SEGMENT;此处输入堆栈段代码STACKS ENDSCODES SEGMENTASSUME CS:CODES,DS:DATAS,ES:DATAS,SS:STACKS START:MOV AX,DATASMOV DS,AXMOV ES,AX;窗口预置drawwindow 1eh,0,0,24,79 ;画主窗口drawwindow 70h,0,0,0,79 ;画菜单窗口drawwindow 70h,24,0,24,79 ;画副窗口;画主窗口上边框windowtandb 0d5h,0cdh,0b8h,1,0,80,1ehMOV AL,2draw:;画主窗口左右边框windowlandr 0b3h,AL,0,80,1ehINC ALCMP AL,17hJNE draw;画主窗口下边框windowtandb 0c0h,0c4h,0d9h,23,0,80,1eh;***************************************开始主菜单绘制outputstr menu1,4,0,3,0Fh ;输出(串,长度,位置,属性)outputstr menu2,4,0,13,70hchangemenu 0,13,1,74houtputstr menu3,3,0,23,70hchangemenu 0,23,1,74houtputstr menu4,4,0,33,70hchangemenu 0,33,1,74houtputstr menu5,4,0,43,70hchangemenu 0,43,1,74h;***************************************结束主菜单绘制;***************************************窗口提示信息输出outputstr msg1,68,3,5,17h;输出(串,长度,位置,属性)changemenu 3,18,5,1eh ;改变属性(起始位置,重复次数,属性)changemenu 3,24,5,1ehchangemenu 3,30,5,1ehchangemenu 3,36,5,1ehchangemenu 3,42,5,1ehchangemenu 3,51,1,1ehoutputstr msg2,51,6,5,17hchangemenu 6,18,11,1ehoutputstr msg3,40,9,5,17hchangemenu 9,18,1,1ehchangemenu 9,23,1,1ehoutputstr msg4,42,12,5,17hchangemenu 12,18,1,1ehchangemenu 12,23,1,1ehoutputstr escape,18,15,5,17hchangemenu 15,11,3,1ehpos 24,0INPUT: ;消息接收循环MOV AH,0INT 16hCMP AH,01h ;ESC退出JNE continue1 ;否则继续CALL exitcontinue1:CMP AH,4bhJNE continue2CALL prsleft ;按左键跳转JMP inputcontinue2:CMP AH,4dhJNE continue3CALL prsright ;按右键跳转JMP inputcontinue3:CMP AH,50hJNE continue4CALL prsdown ;按下键跳转JMP inputcontinue4:CMP AH,21hJNE continue5MOV AH,02hINT 16hAND AL,0fhCMP AL,08hJNE continue5CALL FAlt ;按下ALT+F键跳转JMP inputcontinue5:CMP AH,12hJNE continue6MOV AH,02hINT 16hAND AL,0fhCMP AL,08hJNE continue6CALL EAlt ;按下ALT+E键跳转JMP inputcontinue6:CMP AH,13hJNE continue7MOV AH,02hINT 16hAND AL,0fhCMP AL,08hJNE continue7CALL RAlt ;按下ALT+R键跳转JMP inputcontinue7:CMP AH,14hJNE continue8MOV AH,02hINT 16hAND AL,0fhCMP AL,08hJNE continue8CALL TAlt ;按下ALT+T键跳转JMP inputcontinue8:CMP AH,10hJNE continue9MOV AH,02hINT 16hAND AL,0fhCMP AL,08hJNE continue9CALL QAlt ;按下ALT+Q键跳转JMP inputcontinue9:CMP AH,48hJNE continue10CALL prsup ;按上键跳转JMP inputcontinue10:CMP AH,1chJNE inputCALL prsenter ;按下ENTER键跳转JMP input;----------------------------------------- exit PROC NEAR;退出子过程outputstr over,42,18,5,1ah;显示退出提示信息POS 21,0MOV AH,4chINT 21hRETexit ENDP;----------------------------------------- prsenter PROC NEAR ;按下ENTER键CMP subshow,0JNE enter1CALL prsdown ;子菜单未开启则开启子菜单RETenter1: ;第num号子菜单开启后的处理MOV AL, num ;主菜单号送ALPUSH AXMOV CL,0ahMUL CLSUB AX,07hMOV num,ALDEC numwritescr num,scrmm;对相应菜单写屏INC numpos 0, numPOP AXMOV num,ALdrawwindow 13h,22,4,22,50CMP num,1JNE prsenter1 ;不选择1号主菜单则跳转CMP subnum,2JNE entersub12outputstr sub11,10,22,5,13h;选择子菜单1entersub12:CMP subnum,3JNE entersub13outputstr sub12,11,22,5,13h;选择子菜单2entersub13:CMP subnum,4JNE prsenter1outputstr sub13,11,22,5,13h;选择子菜单3;CALL exitprsenter1:CMP num,2JNE prsenter2 ;不选择2号主菜单则跳转CMP subnum,2JNE entersub22outputstr sub21,10,22,5,13hentersub22:CMP subnum,3JNE entersub23outputstr sub22,11,22,5,13hentersub23:CMP subnum,4JNE prsenter2outputstr sub23,11,22,5,13hprsenter2:CMP num,3JNE prsenter3 ;不选择3号主菜单则跳转CMP subnum,2JNE entersub32outputstr sub31,10,22,5,13hentersub32:CMP subnum,3JNE entersub33outputstr sub32,12,22,5,13hentersub33:CMP subnum,4JNE prsenter3outputstr sub33,11,22,5,13hprsenter3:CMP num,4JNE prsenter4 ;不选择4号主菜单则跳转CMP subnum,2JNE entersub42outputstr sub41,11,22,5,13hentersub42:CMP subnum,3JNE entersub43outputstr sub42,11,22,5,13hentersub43:CMP subnum,4JNE prsenter4outputstr sub43,13,22,5,13hprsenter4:CMP num,5JNE prsenter5 ;不选择5号主菜单则跳转CMP subnum,2JNE entersub52outputstr sub51,12,22,5,13hentersub52:CMP subnum,3JNE entersub53outputstr sub52,10,22,5,13hentersub53:CMP subnum,4JNE prsenter5outputstr sub53,11,22,5,13hCALL exitprsenter5:MOV subshow,0 ;未选择主菜单,子菜单不显示RETprsenter ENDP;-----------------------------------------qalt PROC NEAR;QUIT下的子菜单显示MOV AL, numMOV CL,0ahMUL CLSUB AX,07hMOV num,AL ;计算菜单位置CMP subshow,1JNE qshowDEC numwritescr num,scrmm ;对相应主菜单处写屏,恢复主菜单状态INC numqshow:readscr 42,scrmm ;读屏幕状态submenu 42,submenu51,5,submenu52,3,submenu53,4,9;显示子菜单changemenu 0, num,5,70hchangemenu 0, num,1,74hMOV num,05hchangemenu 0,43,4,0fhchangemenu 2,44,6,0fhMOV subnum,2MOV subshow,1pos 0,43RETqalt ENDP;----------------------------------------- talt PROC NEAR;TOOL下的子菜单显示MOV AL, numMOV CL,0ahMUL CLSUB AX,07hMOV num,ALCMP subshow,1JNE tshowDEC numwritescr num,scrmmINC numtshow:readscr 32,scrmmsubmenu 32,submenu41,4,submenu42,4,submenu43,6,9 changemenu 0, num,5,70hchangemenu 0, num,1,74hMOV num,04hchangemenu 0,33,5,0fhchangemenu 2,34,6,0fhMOV subnum,2MOV subshow,1pos 0,33RETtalt ENDP;----------------------------------------- ralt PROC NEAR;RUN下的子菜单显示MOV AL, numMOV CL,0ahMUL CLSUB AX,07hMOV num,ALCMP subshow,1JNE rshowDEC numwritescr num,scrmmINC numrshow:readscr 22,scrmmsubmenu 22,submenu31,3,submenu32,5,submenu33,4,9 changemenu 0, num,5,70hchangemenu 0, num,1,74hMOV num,03hchangemenu 0,23,3,0fhchangemenu 2,24,6,0fhMOV subnum,2MOV subshow,1pos 0,23RETralt ENDP;----------------------------------------- ealt PROC NEAR;EDIT下的子菜单显示MOV AL, numMOV CL,0ahMUL CLSUB AX,07hMOV num,ALCMP subshow,1JNE eshowDEC numwritescr num,scrmmINC numeshow:readscr 12,scrmmsubmenu 12,submenu21,3,submenu22,4,submenu23,4,9 changemenu 0, num,5,70hchangemenu 0, num,1,74hMOV num,02hchangemenu 0,13,4,0fhchangemenu 2,14,6,0fhMOV subnum,2MOV subshow,1pos 0,13RETealt ENDP;----------------------------------------- falt PROC NEAR;FILE下的子菜单显示MOV AL, numMOV CL,0ahMUL CLSUB AX,07hMOV num,ALCMP subshow,1JNE fshowDEC numwritescr num,scrmmINC numfshow:readscr 2,scrmmsubmenu 2,submenu11,3,submenu12,4,submenu13,4,9changemenu 0, num,5,70hchangemenu 0, num,1,74hMOV num,01hchangemenu 0,3,4,0fhchangemenu 2,4,6,0fhMOV subnum,2MOV subshow,1pos 0,3RETfalt ENDP;----------------------------------------- prsup PROC NEAR; 按上箭头CMP subshow,0;子菜单号为0则不显示JNE prsup2RETprsup2:MOV AL, numPUSH AXMOV CL,0ahMUL CLSUB AX,07hMOV num,ALchangemenu subnum, num,8,70h;恢复被选中子菜单的状态INC numchangemenu subnum, num,1,74h;恢复上一次被选中子菜单的属性POP AXMOV num,ALCMP subnum,02hJNE prsuptopMOV subnum,04h ;从顶部向上则回到底部JMP prsup1prsuptop:DEC subnum ;子菜单号减1prsup1:MOV AL, numPUSH AXMOV CL,0ahMUL CLSUB AX,07hMOV num,ALchangemenu subnum, num,8,0fh;;反显子菜单POP AXMOV num,ALRETprsup ENDP;----------------------------------------- prsdown PROC NEAR; 按下箭头CMP subshow,0 ;子菜单未打开则打开相应的子菜单JNE prsdown2 ;子菜单已打开则跳转CMP num,1JNE prsdown3CALL falt ;打开FILE下的子菜单JMP prsdown7prsdown3:CMP num,2JNE prsdown4CALL ealt ;打开EDIT下的子菜单JMP prsdown7prsdown4:CMP num,3JNE prsdown5CALL ralt ;打开RUN下的子菜单JMP prsdown7prsdown5:CMP num,4JNE prsdown6CALL talt ;打开TOOL下的子菜单JMP prsdown7prsdown6:CALL qalt ;打开QUIT下的子菜单prsdown7:RETprsdown2:MOV AL, numPUSH AXMOV CL,0ahMUL CLSUB AX,07hMOV num,ALchangemenu subnum, num,8,70h;恢复被选中子菜单的状态INC numchangemenu subnum, num,1,74h;恢复上一次被选中子菜单的属性POP AXMOV NUM,ALCMP subnum,04hJNE prsdownbotMOV subnum,02h ;从底部向下则回到顶部JMP prsdown1prsdownbot:INC subnum ;子菜单号加1prsdown1:MOV AL, numPUSH AXMOV CL,0ahMUL CLSUB AX,07hMOV num,ALchangemenu subnum, num,8,0fh;反显子菜单POP AXMOV num,ALRETprsdown ENDP;----------------------------------------- prsright PROC NEAR ; 按右箭头CMP subshow,0JE prsright1CALL prsrgtsub ;子菜单已开启则跳转RETprsright1: ;子菜单未开启的处理MOV AL, numPUSH AXMOV CL,0ahMUL CLSUB AX,07hMOV num,ALchangemenu 0,num,5,70h;恢复当前选中主菜单的状态changemenu 0,num,1,74h;恢复状态POP AXMOV num,ALCMP num,05hJNE prsright2 ;未到达最右边则跳转MOV num,01h ;到达最右边则跳转最左边JMP prsright3prsright2:INC num ;主菜单号加1prsright3: ;置主菜单长度CMP num,1JE prsright4CMP num,2JE prsright4CMP num,5JE prsright4CMP num,3JE prsright5CMP num,4JE prsright4prsright4:MOV index,4JMP prsright7prsright5:MOV index,3prsright7:MOV AL, numPUSH AXMOV CL,0ahMUL CLSUB AX,07hMOV num,ALchangemenu 0, num, index,0fh;反显主菜单POP AXMOV num,ALRETprsright ENDP;----------------------------------------- prsrgtsub PROC NEAR;当子菜单打开时按右箭头CMP num,1JNE prsrgt1CALL ealt ;打开EDIT的子菜单JMP prsrgt5prsrgt1:CMP num,2JNE prsrgt2CALL ralt ;打开RUN的子菜单JMP prsrgt5prsrgt2:CMP num,3JNE prsrgt3CALL talt ;打开TOOL的子菜单JMP prsrgt5prsrgt3:CMP num,4JNE prsrgt4CALL qalt ;打开QUIT的子菜单JMP prsrgt5prsrgt4:CALL falt ;打开FILE的子菜单prsrgt5:RETprsrgtsub ENDP;----------------------------------------- prsleft PROC NEAR;按左箭头CMP subshow,0JE prsleft1CALL prslftsubRETprsleft1:MOV AL, numPUSH AXMOV CL,0ahMUL CLSUB AX,07hMOV num,ALchangemenu 0,num,5,70h ;恢复当前选中主菜单的状态changemenu 0,num,1,74h ;恢复状态POP AXMOV num,ALCMP num,01hJNE prsleft2MOV num,05hJMP prsleft3prsleft2:DEC num ;主菜单号减1prsleft3:CMP num,1JE prsleft4CMP num,2JE prsleft4CMP num,5JE prsleft4CMP num,3JE prsleft5CMP num,4JE prsleft4prsleft4:MOV index,4JMP prsleft7prsleft5:MOV index,3prsleft7:MOV AL, numPUSH AXMOV CL,0ahMUL CLSUB AX,07hMOV num,ALchangemenu 0, num, index,0fh;反显主菜单POP AXMOV num,ALRETprsleft ENDP;----------------------------------------- prslftsub PROC NEAR;当子菜单打开时按左箭头CMP num,1JNE prslft1CALL qalt ;打开QUIT的子菜单JMP prslft5prslft1:CMP num,2JNE prslft2CALL falt ;打开FILE的子菜单JMP prslft5prslft2:CMP num,3JNE prslft3CALL ealt ;打开EDIT的子菜单JMP prslft5prslft3:CMP num,4JNE prslft4CALL ralt ;打开RUN的子菜单JMP prslft5prslft4:CALL talt ;打开TOOL的子菜单prslft5:RETprslftsub ENDP;-----------------------------------------CODES ENDSEND START。