第 9 章 dcc - Crc.exe
9.7.9 Crc.exe
Crc 这个程序计算单字符(1-character) 消息块的循环冗余校验(CRC),然后把求得的 CRC 送回到 CRC 函数,检查“收到的”单字符消息和 CRC 是否正确的。反汇编程序见图 9-47 所示,反编译的 C 程序在图 9-48,最初的 C 程序在图 9-49。Crc 有如下调用图:
main proc_1 proc_2 LXLSH@ LXRSH@ proc_3 proc_2 printf |
从最初的 C 程序可知,crc 有三个函数和一个主要子过程。该程序的反编译版本有五个函数和一个主程序;两个额外的函数是支持长整型右移位和左移位的运行时支持例程 (分别是 LXRSH@和 LXLSH@)。这两个例程最初是用汇编语言编写的,而且被翻译成 C 语言——通过存取长整型参数的低字部分和高字部分。从该程序的统计可知 (见图 9-50),用户函数有中间指令缩减率超过 80%。这些函数有跟最初程序相同数目的高级指令。函数 proc_1 是返回零的 crc_clear 函数。这个函数有中间指令 83.33%的缩减率,归因于子过程序言和尾代码带来的开销。函数 proc_2 是 crc_update 函数,它依照 CCITT 推荐的 CRC 生成器函数来为输入参数计算 CRC。这个函数使用 32 位来计算结果,而且返回较低的 16 位作为该函数的值。这个函数的反编译版本传播以下事实——被调用的运行时例程 LXRSH@的结果只使用其中 16 位,因此这个函数只返回一个整型数(16 位) 而非一个长整型;其代码比相应的 LXLSH@ (它返回一个长整型) 简单得多。指令数目的缩减率达 84.62%。函数 proc_3 是 crc_finish 函数,它返回最后的两个 CRC 字符——在块结束时传输。这个函数调用 crc_update 函数两次;其中一个作为另一个的参数。指令数目的缩减率是很高的(93.75%),因为所有 16 个低级指令被转换成 1 个高级返回指令。最后,主程序以正确的顺序调用函数;达到 82.09%的缩减率。在这个程序中使用整型数而非字符型,因为这样的字符没有使用字符型变量 (即,一个无符号的字符产生相同的代码)。该程序总的中间指令缩减率是 77.78%,这是由于运行时例程而少于 80%。
proc_3 | PROC NEAR | ||||
000 | 000385 | 55 | PUSH | bp | |
001 | 000386 | 8BEC | MOV | bp,sp | |
002 | 000388 | 33C0 | XOR | ax,ax | |
003 | 00038A | 50 | PUSH | ax | |
004 | 00038B | 33C0 | XOR | ax,ax | |
005 | 00038D | 50 | PUSH | ax | |
006 | 00038E | FF7604 | PUSH | word ptr [bp+4] | |
007 | 000391 | E86FFF | CALL | near ptr proc_2 | |
008 | 000394 | 59 | POP | cx | |
009 | 000395 | 59 | POP | cx | |
010 | 000396 | 50 | PUSH | ax | |
011 | 000397 | E869FF | CALL | near ptr proc_2 | |
012 | 00039A | 8BE5 | MOV | sp,bp | |
014 | 00039E | 5D | POP | bp | |
015 | 00039F | C3 | RET | ||
proc_3 | ENDP | ||||
LXRSH@ | PROC FAR | ||||
000 | 001585 | 80F910 | CMP | cl,10h | |
001 | 001588 | 7310 | JAE | L1 | |
002 | 00158A | 8BDA | MOV | bx,dx | |
003 | 00158C | D3E8 | SHR | ax,cl | |
004 | 00158E | D3FA | SAR | dx,cl | |
005 | 001590 | F6D9 | NEG | cl | |
006 | 001592 | 80C110 | ADD | cl,10h | |
007 | 001595 | D3E3 | SHL | bx,cl | |
008 | 001597 | 0BC3 | OR | ax,bx | |
009 | 001599 | CB | RETF | ||
010 | 00159A | 80E910 | L1: SUB | cl,10h | |
011 | 00159D | 8BC2 | MOV | ax,dx | |
012 | 00159F | 99 | CWD | ||
013 | 0015A0 | D3F8 | SAR | ax,cl | |
014 | 0015A2 | CB | RETF | ||
LXRSH@ | ENDP | ||||
proc_1 | PROC NEAR | ||||
000 | 0002FA | 55 | PUSH | bp | |
001 | 0002FB | 8BEC | MOV | bp,sp | |
002 | 0002FD | 33C0 | XOR | ax,ax | |
004 | 000301 | 5D | POP | bp | |
005 | 000302 | C3 | RET | ||
proc_1 | ENDP | ||||
LXLSH@ | PROC FAR | ||||
000 | 0015A3 | 80F910 | CMP | cl,10h | |
001 | 0015A6 | 7310 | JAE | L2 | |
002 | 0015A8 | 8BD8 | MOV | bx,ax | |
003 | 0015AA | D3E0 | SHL | ax,cl | |
004 | 0015AC | D3E2 | SHL | dx,cl | |
005 | 0015AE | F6D9 | NEG | cl | |
006 | 0015B0 | 80C110 | ADD | cl,10h | |
007 | 0015B3 | D3EB | SHR | bx,cl | |
008 | 0015B5 | 0BD3 | OR | dx,bx | |
009 | 0015B7 | CB | RETF | ||
010 | 0015B8 | 80E910 | L2: SUB | cl,10h | |
011 | 0015BB | 8BD0 | MOV | dx,ax | |
012 | 0015BD | 33C0 | XOR | ax,ax | |
013 | 0015BF | D3E2 | SHL | dx,cl | |
014 | 0015C1 | CB | RETF | ||
LXLSH@ | ENDP | ||||
proc_2 | PROC NEAR | ||||
000 | 000303 | 55 | PUSH | bp | |
001 | 000304 | 8BEC | MOV | bp,sp | |
002 | 000306 | 83EC06 | SUB | sp,6 | |
003 | 000309 | 8B4604 | MOV | ax,[bp+4] | |
004 | 00030C | 99 | CWD | ||
005 | 00030D | B108 | MOV | cl,8 | |
006 | 00030F | 9AA3141000 | CALL | far ptr LXLSH@ | |
007 | 000314 | 52 | PUSH | dx | |
008 | 000315 | 50 | PUSH | ax | |
009 | 000316 | 8A4606 | MOV | al,[bp+6] | |
010 | 000319 | 98 | CWD | ||
011 | 00031A | 99 | CWD | ||
012 | 00031B | 5B | POP | bx | |
013 | 00031C | 59 | POP | cx | |
014 | 00031D | 03D8 | ADD | bx,ax | |
015 | 00031F | 13CA | ADC | cx,dx | |
016 | 000321 | 894EFC | MOV | [bp-4],cx | |
017 | 000324 | 895EFA | MOV | [bp-6],bx | |
018 | 000327 | C746FE0000 | MOV | word ptr [bp-2],0 | |
020 | 000365 | 837EFE08 | L3: CMP | word ptr [bp-2],8 | |
021 | 000369 | 7CC3 | JL | L4 | |
022 | 00036B | 8B56FC | MOV | dx,[bp-4] | |
023 | 00036E | 8B46FA | MOV | ax,[bp-6] | |
024 | 000371 | 2500FF | AND | ax,0FF00h | |
025 | 000374 | 81E2FF00 | AND | dx,0FFh | |
026 | 000378 | B108 | MOV | cl,8 | |
027 | 00037A | 9A85141000 | CALL | far ptr LXRSH@ | |
029 | 000381 | 8BE5 | MOV | sp,bp | |
030 | 000383 | 5D | POP | bp | |
031 | 000384 | C3 | RET | ||
032 | 00032E | 8B56FC | L4: MOV | dx,[bp-4] | |
033 | 000331 | 8B46FA | MOV | ax,[bp-6] | |
034 | 000334 | D1E0 | SHL | ax,1 | |
035 | 000336 | D1D2 | RCL | dx,1 | |
036 | 000338 | 8956FC | MOV | [bp-4],dx | |
037 | 00033B | 8946FA | MOV | [bp-6],ax | |
038 | 00033E | 8B56FC | MOV | dx,[bp-4] | |
039 | 000341 | 8B46FA | MOV | ax,[bp-6] | |
040 | 000344 | 250000 | AND | ax,0 | |
041 | 000347 | 81E20001 | AND | dx,100h | |
042 | 00034B | 0BD0 | OR | dx,ax | |
043 | 00034D | 7413 | JE | L5 | |
044 | 00034F | 8B56FC | MOV | dx,[bp-4] | |
045 | 000352 | 8B46FA | MOV | ax,[bp-6] | |
046 | 000355 | 350021 | XOR | ax,2100h | |
047 | 000358 | 81F21001 | XOR | dx,110h | |
048 | 00035C | 8956FC | MOV | [bp-4],dx | |
049 | 00035F | 8946FA | MOV | [bp-6],ax | |
050 | 000362 | FF46FE | L5: INC | word ptr [bp-2] | |
051 | JMP | L3 | ;Synthetic inst | ||
proc_2 | ENDP | ||||
main | PROC NEAR | ||||
000 | 0003A0 | 55 | PUSH | bp | |
001 | 0003A1 | 8BEC | MOV | bp,sp | |
002 | 0003A3 | 83EC06 | SUB | sp,6 | |
003 | 0003A6 | C646FD41 | MOV | byte ptr [bp-3],41h | |
004 | 0003AA | E84DFF | CALL | near ptr proc_1 | |
005 | 0003AD | 8946FA | MOV | [bp-6],ax | |
006 | 0003B0 | 8A46FD | MOV | al,[bp-3] | |
007 | 0003B3 | 98 | CWD | ||
008 | 0003B4 | 50 | PUSH | ax | |
009 | 0003B5 | FF76FA | PUSH | word ptr [bp-6] | |
010 | 0003B8 | E848FF | CALL | near ptr proc_2 | |
011 | 0003BB | 59 | POP | cx | |
012 | 0003BC | 59 | POP | cx | |
013 | 0003BD | 8946FA | MOV | [bp-6],ax | |
014 | 0003C0 | FF76FA | PUSH | word ptr [bp-6] | |
015 | 0003C3 | E8BFFF | CALL | near ptr proc_3 | |
016 | 0003C6 | 59 | POP | cx | |
017 | 0003C7 | 8946FA | MOV | [bp-6],ax | |
018 | 0003CA | 8B46FA | MOV | ax,[bp-6] | |
019 | 0003CD | 2500FF | AND | ax,0FF00h | |
020 | 0003D0 | B108 | MOV | cl,8 | |
021 | 0003D2 | D3E8 | SHR | ax,cl | |
022 | 0003D4 | 8846FE | MOV | [bp-2],al | |
023 | 0003D7 | 8A46FA | MOV | al,[bp-6] | |
024 | 0003DA | 24FF | AND | al,0FFh | |
025 | 0003DC | 8846FF | MOV | [bp-1],al | |
026 | 0003DF | FF76FA | PUSH | word ptr [bp-6] | |
027 | 0003E2 | B89401 | MOV | ax,194h | |
028 | 0003E5 | 50 | PUSH | ax | |
029 | 0003E6 | E8FC08 | CALL | near ptr printf | |
030 | 0003E9 | 59 | POP | cx | |
031 | 0003EA | 59 | POP | cx | |
032 | 0003EB | E80CFF | CALL | near ptr proc_1 | |
033 | 0003EE | 8946FA | MOV | [bp-6],ax | |
034 | 0003F1 | 8A46FD | MOV | al,[bp-3] | |
035 | 0003F4 | 98 | CWD | ||
036 | 0003F5 | 50 | PUSH | ax | |
037 | 0003F6 | FF76FA | PUSH | word ptr [bp-6] | |
038 | 0003F9 | E807FF | CALL | near ptr proc_2 | |
039 | 0003FC | 59 | POP | cx | |
040 | 0003FD | 59 | POP | cx | |
041 | 0003FE | 8946FA | MOV | [bp-6],ax | |
042 | 000401 | 8A46FE | MOV | al,[bp-2] | |
043 | 000404 | 98 | CWD | ||
044 | 000405 | 50 | PUSH | ax | |
045 | 000406 | FF76FA | PUSH | word ptr [bp-6] | |
046 | 000409 | E8F7FE | CALL | near ptr proc_2 | |
047 | 00040C | 59 | POP | cx | |
048 | 00040D | 59 | POP | cx | |
049 | 00040E | 8946FA | MOV | [bp-6],ax | |
050 | 000411 | 8A46FF | MOV | al,[bp-1] | |
051 | 000414 | 98 | CWD | ||
052 | 000415 | 50 | PUSH | ax | |
053 | 000416 | FF76FA | PUSH | word ptr [bp-6] | |
054 | 000419 | E8E7FE | CALL | near ptr proc_2 | |
055 | 00041C | 59 | POP | cx | |
056 | 00041D | 59 | POP | cx | |
057 | 00041E | 8946FA | MOV | [bp-6],ax | |
058 | 000421 | FF76FA | PUSH | word ptr [bp-6] | |
059 | 000424 | B89A01 | MOV | ax,19Ah | |
060 | 000427 | 50 | PUSH | ax | |
061 | 000428 | E8BA08 | CALL | near ptr printf | |
062 | 00042B | 59 | POP | cx | |
063 | 00042C | 59 | POP | cx | |
064 | 00042D | 8BE5 | MOV | sp,bp | |
065 | 00042F | 5D | POP | bp | |
066 | 000430 | C3 | RET | ||
main | ENDP |
图 9-47: Crc.a2
/* * Input file : crc.exe * File type : EXE */ #include "dcc.h" int proc_1 () /* Takes no parameters. * High-level language prologue code. */ { return (0); } long LXLSH@ (long arg0, char arg1) /* Uses register arguments: * arg0 = dx:ax. * arg1 = cl. * Runtime support routine of the compiler. */ { int loc1; /* bx */ if (arg1 < 16) { loc1 = LO(arg0); LO(arg0) = (LO(arg0) << arg1); HI(arg0) = (HI(arg0) << arg1); HI(arg0) = (HI(arg0) | (loc1 >> (!arg1 + 16))); return (arg0); } else { HI(arg0) = LO(arg0); LO(arg0) = 0; HI(arg0) = (HI(arg0) << (arg1 - 16)); return (arg0); } } int LXRSH@ (long arg0, char arg1) /* Uses register arguments: * arg0 = dx:ax. * arg1 = cl. * Runtime support routine of the compiler. */ { int loc1; /* bx */ if (arg1 < 16) { loc1 = HI(arg0); LO(arg0) = (LO(arg0) >> arg1); HI(arg0) = (HI(arg0) >> arg1); return ((LO(arg0) | (loc1 << (!arg1 + 16)))); } else { return ((HI(arg0) >> (arg1 - 16))); } } int proc_2 (int arg0, unsigned char arg1) /* Takes 4 bytes of parameters. * High-level language prologue code. * C calling convention. */ { int loc1; long loc2; loc2 = (LXLSH@ (arg0, 8) + arg1); loc1 = 0; while ((loc1 < 8)) { loc2 = (loc2 << 1); if ((loc2 & 0x1000000) != 0) { loc2 = (loc2 ^ 0x1102100); } loc1 = (loc1 + 1); } return (LXRSH@ ((loc2 & 0xFFFF00), 8)); } int proc_3 (int arg0) /* Takes 2 bytes of parameters. * High-level language prologue code. * C calling convention. */ { return (proc_2 (proc_2 (arg0, 0), 0)); } void main () /* Takes no parameters. * High-level language prologue code. */ { int loc1; int loc2; int loc3; int loc4; loc1 = 65; loc2 = proc_1 (); loc2 = proc_2 (loc2, loc1); loc2 = proc_3 (loc2); loc3 = ((loc2 & 0xFF00) >> 8); loc4 = (loc2 & 255); printf ("%04x\n", loc2); loc2 = proc_1 (); loc2 = proc_2 (loc2, loc1); loc2 = proc_2 (loc2, loc3); loc2 = proc_2 (loc2, loc4); printf ("%04x\n", loc2); } |
图 9-48: Crc.b
/* * crc_clear: * This function clears the CRC to zero. It should be called prior to * the start of the processing of a block for both received messages, * and messages to be transmitted. * * Calling sequence: * * short crc; * crc = crc_clear(); */ short crc_clear() { return(0); } /* * crc_update: * this function must be called once for each character which is * to be included in the CRC for messages to be transmitted. * This function is called once for each character which is included * in the CRC of a received message, AND once for each of the two CRC * characters at the end of the received message. If the resulting * CRC is zero, then the message has been correctly received. * * Calling sequence: * * crc = crc_update(crc,next_char); */ short crc_update(crc,crc_char) short crc; char crc_char; { long x; short i; /* "x" will contain the character to be processed in bits 0-7 and the CRC */ /* in bits 8-23. Bit 24 will be used to test for overflow, and then cleared */ /* to prevent the sign bit of "x" from being set to 1. Bits 25-31 are not */ /* used. ("x" is treated as though it is a 32 bit register). */ x = ((long)crc << 8) + crc_char; /* Get the CRC and the character */ /* Repeat the following loop 8 times (for the 8 bits of the character). */ for(i = 0;i < 8;i++) { /* Shift the high-order bit of the character into the low-order bit of the */ /* CRC, and shift the high-order bit of the CRC into bit 24. */ x = x << 1; /* Shift "x" left one bit */ /* Test to see if the old high-order bit of the CRC was a 1. */ if(x & 0x01000000) /* Test bit 24 of "x" */ /* If the old high-order bit of the CRC was a 1, exclusive-or it with a one */ /* to set it to 0, and exclusive-or the CRC with hex 1021 to produce the */ /* CCITT-recommended CRC generator of: X**16 + X**12 + X**5 + 1. To produce */ /* the CRC generator of: X**16 + X**15 + X**2 + 1, change the constant from */ /* 0x01102100 to 0x01800500. This will exclusive-or the CRC with hex 8005 */ /* and produce the same CRC that IBM uses for their synchronous transmission */ /* protocols. */ x = x ^ 0x01102100; /* Exclusive-or "x" with a...*/ /* ...constant of hex 01102100 */ /* And repeat 8 times. */ } /* End of "for" loop */ /* Return the CRC as the 16 low-order bits of this function's value. */ return(((x & 0x00ffff00) >> 8)); /* AND off the unneeded bits and... */ /* ...shift the result 8 bits to the right */ } /* * crc_finish: * This function must be called once after all the characters in a block * have been processed for a message which is to be TRANSMITTED. It * returns the calculated CRC bytes, which should be transmitted as the * two characters following the block. The first of these 2 bytes * must be taken from the high-order byte of the CRC, and the second * must be taken from the low-order byte of the CRC. This routine is NOT * called for a message which has been RECEIVED. * * Calling sequence: * * crc = crc_finish(crc); */ short crc_finish(crc) short crc; { /* Call crc_update twice, passing it a character of hex 00 each time, to */ /* flush out the last 16 bits from the CRC calculation, and return the */ /* result as the value of this function. */ return(crc_update(crc_update(crc,'\0'),'\0')); } /* * This is a sample of the use of the CRC functions, which calculates the * CRC for a 1-character message block, and then passes the resulting CRC back * into the CRC functions to see if the "received" 1-character message and CRC * are correct. */ main() { short crc; /* The calculated CRC */ char crc_char; /* The 1-character message */ char x, y; /* 2 places to hold the 2 "received" CRC bytes */ crc_char = 'A'; /* Define the 1-character message */ crc = crc_clear(); /* Reset the CRC to "transmit" a new message */ crc = crc_update(crc,crc_char); /* Update the CRC for the first... */ /* ...(and only) character of the message */ crc = crc_finish(crc); /* Finish the transmission calculation */ x = (char)((crc & 0xff00) >> 8); /* Extract the high-order CRC byte */ y = (char)(crc & 0x00ff); /* And extract the low-order byte */ printf("%04x\n",crc); /* Print the results */ crc = crc_clear(); /* Prepare to "receive" a message */ crc = crc_update(crc,crc_char); /* Update the CRC for the first... */ /* ...(and only) character of the message */ crc = crc_update(crc,x); /* Pass both bytes of the "received"... */ crc = crc_update(crc,y); /* ...CRC through crc_update, too */ printf("%04x\n",crc); /* If the result was 0, then the message... */ /* ...was received without error */ } |
图 9-49: Crc.c
子程序 | 低级 | 高级 | % 缩减率 |
proc_1 | 6 | 1 | 83.33 |
LXLSH@ | 15 | 10 | 33.33 |
LXRSH@ | 15 | 6 | 60.00 |
proc_2 | 52 | 8 | 84.62 |
proc_3 | 16 | 1 | 93.75 |
main | 67 | 12 | 82.09 |
合计 | 171 | 38 | 77.78 |
图 9-50: Crc 统计
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论