太可怕了……是我想多了吗……
; by forest93, 2013 data SEGMENT ;提示字符串 prompt DB "[Input 2 UInt16]请输入两个整数,以换行符分隔。$" promptAdd DB "a + b = $" promptInc DB "a + 1 = $" promptSub DB "a - b = $" ;输入/输出缓冲区 outBuffer DB 255 dup (0) inputBufferLength DB 255 inputLength DB 0 inputBuffer DB 255 dup (0) dosInputBuffer = inputBufferLength data ENDS code SEGMENT ASSUME DS:data Main PROC MOV AX, data MOV DS, AX ;cout << prompt PUSH OFFSET prompt CALL OutputString ;输入第一个数 --> bx CALL InputInt CALL Endl MOV BX, AX ;输入第二个数 --> cx(ax) CALL InputInt CALL Endl MOV CX, AX ADD AX, BX PUSH OFFSET promptAdd ;a + b CALL OutputString PUSH AX CALL OutputInt CALL Endl MOV AX, BX INC AX PUSH OFFSET promptInc ;a + 1 CALL OutputString PUSH AX CALL OutputInt CALL Endl MOV AX, BX SUB AX, CX PUSH OFFSET promptSub ;a - b CALL OutputString PUSH AX CALL OutputInt CALL Endl MOV AX, 4C05h ;DOS 返回值 05H INT 21h Main ENDP ;向控制台输出一个字符串 OutputString PROC NEAR ;__stdcall uint16 (uint16 buffer) ; LoMem ;DX <- SP ;BP ;AX ;IP ;buffer ; HiMem PUSH AX PUSH BP PUSH DX MOV BP, SP MOV DX, [BP+8] MOV AH, 09h INT 21h POP DX POP BP POP AX RET 2 OutputString ENDP ;向控制台输出一个换行符 Endl PROC NEAR PUSH AX PUSH DX MOV AH, 2 MOV DL, 0DH INT 21h MOV DL, 0AH INT 21h POP DX POP AX RET Endl ENDP ;从控制台输入一个整数 InputInt PROC NEAR ;__stdcall uint16() PUSH BX ;输入数字字符串 LEA DX, dosInputBuffer MOV AH, 0AH INT 21h MOV BL, inputLength MOV BH, 0 MOV inputBuffer[BX], '$' ;设置字符串结束标识 ;将字符串转换为整数 PUSH OFFSET inputBuffer CALL Str2Int POP BX RET InputInt ENDP ;向控制台输出一个整数 OutputInt PROC NEAR ;__stdcall uint16 (uint16 num) ; LoMem ;DX <- SP ;BP ;AX ;IP ;num ; HiMem PUSH AX PUSH BP PUSH DX MOV BP, SP PUSH OFFSET outBuffer PUSH [BP+8] ;num CALL Int2Str LEA DX, outBuffer MOV AH, 09h INT 21h POP DX POP BP POP AX RET 2 OutputInt ENDP ;将文本转换为数字 Str2Int PROC NEAR ;__stdcall uint16 (char DS:* buffer) ; LoMem ;DX <- SP ;CX ;BX ;IP ;buffer ; HiMem PUSH BX PUSH CX PUSH DX MOV BX, SP MOV BX, SS:[BX+8] ;buffer MOV AX, 0 ;乘10,然后加上当前位 Mul10: MOV CX, 10 MUL CX MOV CL, [BX] ;换一个寄存器操作,避免引起 AX 溢出 SUB CL, '0' ADD AX, CX INC BX CMP [BX], '$' JNE Mul10 POP DX POP CX POP BX RET 2 ;返回值在 AX 里面 Str2Int ENDP ;将数字转换为文本 Int2Str PROC NEAR ;__stdcall (uint16 num, char DS:* buffer) ;参数从右往左压入堆栈 ; LoMem ;DX <- SP ;CX ;BX ;AX ;IP ;num ;buffer ; HiMem PUSH AX PUSH BX PUSH CX PUSH DX MOV BX, SP MOV AX, SS:[BX+10] ;num MOV BX, SS:[BX+12] ;buffer ;试除10,以确定数字位数 MOV CX, 10 PUSH AX TestDiv10: MOV DX, 0 DIV CX INC BX CMP AX, 0 JNZ TestDiv10 MOV [BX], '$' ;加入结束标识 ;除10求余 POP AX Div10: MOV DX, 0 ;or XOR DX, DX DIV CX ADD DL, '0' ;or ADD DL, 30H DEC BX ;从右向左移动指针 MOV [BX], DL CMP AX, 0 JNZ Div10 POP DX POP CX POP BX POP AX RET 4 Int2Str ENDP code ENDS END main
使用 EMU8086 完成编写和调试。
然而很明显,编译器/解释器不支持中文字符……
我们需要解决方案!
只能强行插字节码了……
prompt DB 0C7H,0EBH,0CAH,0E4H,0C8H,0EBH,0C1H,0BDH,0B8H,0F6H,0D5H,0FBH,0CAH,0FDH,0A3H,0ACH,0D2H,0D4H,0BBH,0BBH,0D0H,0D0H,0B7H,0FBH,0B7H,0D6H,0B8H,0F4H,0A1H,0A3H,"$"
在 MS-DOS 中运行中文字符系统后,终于出来了:
总之,多少有点儿蛋疼。