太可怕了……是我想多了吗……
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 |
; 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 完成编写和调试。
然而很明显,编译器/解释器不支持中文字符……
我们需要解决方案!
只能强行插字节码了……
4 |
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 中运行中文字符系统后,终于出来了:
总之,多少有点儿蛋疼。