一、比较表:
第一章第一节中所提及的排序程式测试结果如下: ┌──────┬─────────┬────────┐ │ 项 目│ C │组 合 语 言 │ ├──────┼─────────┼────────┤ │源程式长度 │ 1,363 Bytes│ 3,581 Bytes│ │执行程式长度│ 69,345 Bytes│ 803 Bytes│ │编程时间 │ 20 小时 │ 80 小时 │ │8,000 笔需时│ 30 秒 │ 8 秒 │ │48,000笔需时│ 640KB中, 无法执行│ 70 秒 │ └──────┴─────────┴────────┘
组合语言在大量资料处理时,应用灵活,而C语言因受到空间限制,以目前之系统空间,无法执行。 测试时间: 1989年 9月12至18日。 参加人员: 张达权,段旭光,李朝辉。 使用机种: IBM PS/2-50,80286 CPU,8MHZ。 使用语言: C及组合语言。 因其他语言皆无法胜任,故仅选用此二者。 处理对象: 48,000个中文词组,分别取自12个资料档中。 每档有 4,000个词组。 每个词组有一至五个中文字。 每个中文字占两个字元内码。 全部资料占 316,421字元。 排序方式: 按仓颉字母顺位排列。 为了效率,采用SHELL 排序法。
二、组合语言之制作:
1: CG SEGMENT 2: ASSUME CS:CG,DS:CG,ES:CG 3: ORG 100H 4: START: 5: MOV AX,CS 6: MOV DS,AX 7: MOV SI,130 ; 指向输入缓冲区 8: MOV BL,[SI-2] 9: DEC BX 10: SUB BH,BH 11: MOV [BX][SI],BH 12: CLD 13: MOV DX,SI 14: MOV AX,3D00H 15: INT 21H ; 打开源档 16: JNC ZSTART 17: MOV DX,OFFSET ZSTR1 ; 若无此档则退出 18: MOV AH,9 19: INT 21H 20: INT 20H 21: ZSTART: 22: MOV BX,AX 23: SUB DX,DX 24: MOV CX,8000H 25: MOV BP,4D00H 26: MOV DS,BP 27: ZREAD: 28: MOV AH,3FH ; 读档 29: INT 21H 30: OR AX,AX 31: JZ ZREND 32: MOV AX,DS ; 未完,换段再读 33: ADD AX,800H 34: MOV DS,AX 35: JMP ZREAD 36: ZREND: 37: MOV AH,3EH ; 关档 38: INT 21H 39: MOV AX,2400H 40: MOV ES,AX 41: SUB DI,DI 42: SUB SI,SI 43: MOV DS,BP 44: SUB BP,BP 45: ZC1: 46: CALL ZCHGSEG 47: MOV CX,5 ; 将不等长换为等长 48: ZC3: 49: LODSW 50: CMP AL,0DH 51: JZ ZC4 52: STOSW 53: LOOP ZC3 54: INC SI 55: INC SI 56: JMP SHORT ZC5 57: ZC4: 58: MOV AX,2020H 59: REP STOSW 60: ZC5: 61: INC BP 62: LODSB 63: DEC SI 64: CMP AL,1AH 65: JNZ ZC1 66: STOSB 67: MOV CS:ZBW2,BP ; BP为资料计数 68: CALL ZSORT ; 排序 69: CALL ZDEL ; 删除相同者 70: CALL ZTR ; 换为不等长方式 71: MOV SI,DX 72: SUB CX,CX 73: PUSH CS 74: POP DS 75: MOV DX,OFFSET ZFCB ; 将结果存档 76: MOV AH,3CH 77: INT 21H 78: MOV BX,AX 79: MOV AX,2400H 80: MOV DS,AX 81: SUB DX,DX 82: OR SI,SI 83: JZ ZC7 84: MOV CX,8000H 85: ZC6: 86: MOV AH,40H 87: INT 21H 88: MOV AX,DS 89: ADD AX,800H 90: MOV DS,AX 91: DEC SI 92: JNZ ZC6 93: ZC7: 94: MOV CX,DI 95: MOV AH,40H 96: INT 21H 97: MOV AH,3EH 98: INT 21H 99: INT 20H 100: ZSORT: ; 排序子程式 101: SHR BP,1 102: ZS0: 103: PUSH BP 104: MOV CS:ZBW1,BP 105: MOV AX,CS:ZBW2 106: SUB AX,BP 107: MOV DX,BP 108: MOV BP,AX 109: MOV DI,2400H 110: MOV DS,DI 111: SUB SI,SI 112: CALL ZFINDES 113: ADD BX,DI 114: MOV ES,BX 115: MOV DI,AX 116: SUB DX,DX 117: ZS1: 118: CALL ZCOMPS 119: JBE ZS4 120: CALL ZXCHG 121: PUSH DS 122: PUSH ES 123: PUSH SI 124: PUSH DI 125: PUSH DX 126: ZS2: 127: MOV DI,SI 128: MOV AX,DS 129: MOV ES,AX 130: SUB DX,CS:ZBW1 131: JC ZS3 132: CALL ZFINDES 133: MOV SI,AX 134: ADD BX,2400H 135: MOV DS,BX 136: CALL ZCOMPS 137: JBE ZS3 138: CALL ZXCHG 139: JMP ZS2 140: ZS3: 141: POP DX 142: POP DI 143: POP SI 144: POP ES 145: POP DS 146: ZS4: 147: ADD SI,10 148: JS ZS7 149: ZS5: 150: ADD DI,10 151: JS ZS8 152: ZS6: 153: INC DX 154: CMP DX,BP 155: JNZ ZS1 156: POP BP 157: SHR BP,1 158: JNZ ZS0 159: RET 160: ZS7: 161: SUB SI,8000H 162: MOV AX,DS 163: ADD AX,800H 164: MOV DS,AX 165: JMP ZS5 166: ZS8: 167: SUB DI,8000H 168: MOV AX,ES 169: ADD AX,800H 170: MOV ES,AX 171: JMP ZS6 172: ZFINDES: 173: SUB BX,BX 174: MOV AX,DX 175: SHL AX,1 176: RCL BX,1 177: SHL AX,1 178: RCL BX,1 179: ADD AX,DX 180: ADC BX,0 181: SHL AX,1 182: RCL BX,1 183: PUSH AX 184: MOV CL,4 185: SHR AX,CL 186: MOV CL,12 187: SHL BX,CL 188: ADD BX,AX 189: POP AX 190: AND AX,15 191: RET 192: ZXCHG: 193: MOV CL,5 194: ZXCHG1: 195: LODSW 196: MOV BX,ES:[DI] 197: STOSW 198: MOV [SI-2],BX 199: LOOP ZXCHG1 200: SUB SI,10 201: SUB DI,10 202: RET 203: ZCOMPS: 204: MOV CL,5 205: MOV AX,DI 206: MOV BX,SI 207: REPZ CMPSB 208: MOV SI,BX 209: MOV DI,AX 210: RET 211: ZTR: ; 将等长串换为不等长串 212: MOV AX,2400H 213: MOV DS,AX 214: MOV ES,AX 215: SUB SI,SI 216: MOV DI,SI 217: MOV BP,CS:ZBW2 218: MOV DX,SI 219: ZTR1: 220: MOV CL,5 221: LODSW 222: CMP AX,2020H 223: JNZ ZTR21 224: ADD SI,8 225: DEC BP 226: JMP ZTR1 227: ZTR2: 228: LODSW 229: CMP AX,2020H 230: JZ ZTR3 231: ZTR21: 232: STOSW 233: ZTR3: 234: LOOP ZTR2 235: MOV AX,0A0DH 236: STOSW 237: DEC BP 238: JZ ZTR4 239: CALL ZCHGSEG 240: JMP ZTR1 241: ZTR4: 242: MOV AL,1AH 243: STOSB 244: RET 245: ZCHGSEG: ; 换段子程式 246: OR SI,SI 247: JNS ZCH1 248: SUB SI,BX 249: MOV AX,DS 250: ADD AX,800H 251: MOV DS,AX 252: ZCH1: 253: OR DI,DI 254: JNS ZCH2 255: SUB DI,BX 256: MOV AX,ES 257: ADD AX,800H 258: MOV ES,AX 259: INC DX 260: ZCH2: 261: RET 262: ZDEL: ; 删除相同字串 263: MOV AX,2400H 264: MOV DS,AX 265: MOV ES,AX 266: SUB SI,SI 267: MOV DI,10 268: MOV BP,CS:ZBW2 269: MOV BX,8000H 270: ZDEL1: 271: DEC BP 272: JZ ZCH2 273: MOV AX,SI 274: PUSH DI 275: MOV CL,10 276: REPZ CMPSB 277: POP DI 278: MOV SI,AX 279: JNZ ZDEL2 280: MOV AX,2020H 281: MOV [SI],AX 282: ZDEL2: 283: ADD SI,10 284: ADD DI,10 285: CALL ZCHGSEG 286: JMP ZDEL1 287: ZBW1 DW 0 288: ZBW2 DW 0 289: ZFCB DB 'YRRR',0 290: ZSTR1 DB 'FILE NOT FOUND !$' 291: CG ENDS 292: END START
本段程式,计用了80小时,源程式为 3,581字元,执行程式则为 803 字元。执行48,000词组排序,需时70秒。 及后,因为C语言所写的程式,无法处理48,000个词组,一直试到8,000 条,C才能胜任。再用组合语言程式测试,仅需时8秒。
三、C 语言之制作过程:
我们用相同的方法,利用C写作如下程式: 1: # include <fcntl.h> 2: # include <sys/stat.h> 3: 4: extern unsigned char yr[]; 5: 6: main(argc, argv) 7: int argc; 8: char *argv[]; 9: { 10: int i, n, fd, result; 11: long rsum; 12: unsigned char *yrp[8000], *yrptr, eof[1]; 13: 14: fd = open(argv[1], O_RDWR); 15: rsum = 0; 16: while ((result = read(fd, &yr[rsum], 16384)) > 0) 17: { 18: rsum += result; 19: printf("%d %ld/n", result, rsum); 20: } 21: close(fd); 22: printf("after reading file/n"); 23: fd = creat(argv[1], S_IREAD | S_IWRITE); 24: printf("after creat file/n"); 25: yrp[0] = yrptr = yr; 26: n = 1; 27: while (*yrptr && n < 8000) 28: { 29: while (*yrptr++ != '/n'); 30: yrp[n++] = yrptr; 31: } 32: sort(yrp, n); 33: for (i = 0; i < n; i++) 34: { 35: yrptr = yrp[i]; 36: do 37: { 38: write(fd, yrptr, 1); 39: } while (*yrptr++ != '/n'); 40: } 41: eof[0] = 0x1a; 42: write(fd, eof, 1); 43: close(fd); 44: } 45: 46: 47: sort(v, n) 48: unsigned char *v[]; 49: int n; 50: { 51: int gap, i, j; 52: unsigned char *temp; 53: 54: printf("enter sorting/n"); 55: for (gap = n / 2; gap > 0; gap /= 2) 56: for (i = gap; i < n; i++) 57: for (j = i - gap; j >= 0; j -= gap) 58: { 59: if (strcmp(v[j], v[j + gap]) <= 0) 60: break; 61: /* printf("swapping/n");*/ 62: temp = v[j]; 63: v[j] = v[j + gap]; 64: v[j + gap] = temp; 65: } 66: } 67: 68: strcmp(v1, v2) 69: unsigned char *v1, *v2; 70: { 71: /* printf("enter strcmp/n");*/ 72: for (; *v1 == *v2; v1++, v2++) 73: if (*v1 == '/n') 74: return(0); 75: return(*v1 - *v2); 76: }
本段程式由设计到制作完成,仅用了20小时。但在测试时,花了不少时间,费尽心机,始终无法令本程式运行,原因是资料太大系统空间不够。 最后不得已将资料删至8,000 条,才运行成功,需时30秒。  
|