返回介绍

第 9 章 dcc - Crc.exe

发布于 2025-03-09 23:09:35 字数 28846 浏览 0 评论 0 收藏 0

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_3PROC NEAR   
00000038555PUSHbp 
0010003868BECMOVbp,sp 
00200038833C0XORax,ax 
00300038A50PUSHax 
00400038B33C0XORax,ax 
00500038D50PUSHax 
00600038EFF7604PUSHword ptr [bp+4] 
007000391E86FFFCALLnear ptr proc_2 
00800039459POPcx 
00900039559POPcx 
01000039650PUSHax 
011000397E869FFCALLnear ptr proc_2 
01200039A8BE5MOVsp,bp 
01400039E5DPOPbp 
01500039FC3RET  
 proc_3ENDP   
      
 LXRSH@PROC FAR   
00000158580F910CMPcl,10h 
0010015887310JAEL1 
00200158A8BDAMOVbx,dx 
00300158CD3E8SHRax,cl 
00400158ED3FASARdx,cl 
005001590F6D9NEGcl 
00600159280C110ADDcl,10h 
007001595D3E3SHLbx,cl 
0080015970BC3ORax,bx 
009001599CBRETF  
01000159A80E910L1: SUBcl,10h 
01100159D8BC2MOVax,dx 
01200159F99CWD  
0130015A0D3F8SARax,cl 
0140015A2CBRETF  
 LXRSH@ENDP   
      
 proc_1PROC NEAR   
0000002FA55PUSHbp 
0010002FB8BECMOVbp,sp 
0020002FD33C0XORax,ax 
0040003015DPOPbp 
005000302C3RET  
 proc_1ENDP   
      
 LXLSH@PROC FAR   
0000015A380F910CMPcl,10h 
0010015A67310JAEL2 
0020015A88BD8MOVbx,ax 
0030015AAD3E0SHLax,cl 
0040015ACD3E2SHLdx,cl 
0050015AEF6D9NEGcl 
0060015B080C110ADDcl,10h 
0070015B3D3EBSHRbx,cl 
0080015B50BD3ORdx,bx 
0090015B7CBRETF  
0100015B880E910L2: SUBcl,10h 
0110015BB8BD0MOVdx,ax 
0120015BD33C0XORax,ax 
0130015BFD3E2SHLdx,cl 
0140015C1CBRETF  
 LXLSH@ENDP   
      
 proc_2PROC NEAR   
00000030355PUSHbp 
0010003048BECMOVbp,sp 
00200030683EC06SUBsp,6 
0030003098B4604MOVax,[bp+4] 
00400030C99CWD  
00500030DB108MOVcl,8 
00600030F9AA3141000CALLfar ptr LXLSH@ 
00700031452PUSHdx 
00800031550PUSHax 
0090003168A4606MOVal,[bp+6] 
01000031998CWD  
01100031A99CWD  
01200031B5BPOPbx 
01300031C59POPcx 
01400031D03D8ADDbx,ax 
01500031F13CAADCcx,dx 
016000321894EFCMOV[bp-4],cx 
017000324895EFAMOV[bp-6],bx 
018000327C746FE0000MOVword ptr [bp-2],0 
020000365837EFE08L3: CMPword ptr [bp-2],8 
0210003697CC3JLL4 
02200036B8B56FCMOVdx,[bp-4] 
02300036E8B46FAMOVax,[bp-6] 
0240003712500FFANDax,0FF00h 
02500037481E2FF00ANDdx,0FFh 
026000378B108MOVcl,8 
02700037A9A85141000CALLfar ptr LXRSH@ 
0290003818BE5MOVsp,bp 
0300003835DPOPbp 
031000384C3RET  
03200032E8B56FCL4: MOVdx,[bp-4] 
0330003318B46FAMOVax,[bp-6] 
034000334D1E0SHLax,1 
035000336D1D2RCLdx,1 
0360003388956FCMOV[bp-4],dx 
03700033B8946FAMOV[bp-6],ax 
03800033E8B56FCMOVdx,[bp-4] 
0390003418B46FAMOVax,[bp-6] 
040000344250000ANDax,0 
04100034781E20001ANDdx,100h 
04200034B0BD0ORdx,ax 
04300034D7413JEL5 
04400034F8B56FCMOVdx,[bp-4] 
0450003528B46FAMOVax,[bp-6] 
046000355350021XORax,2100h 
04700035881F21001XORdx,110h 
04800035C8956FCMOV[bp-4],dx 
04900035F8946FAMOV[bp-6],ax 
050000362FF46FEL5: INCword ptr [bp-2] 
051  JMPL3;Synthetic inst
 proc_2ENDP   
      
 mainPROC NEAR   
0000003A055PUSHbp 
0010003A18BECMOVbp,sp 
0020003A383EC06SUBsp,6 
0030003A6C646FD41MOVbyte ptr [bp-3],41h 
0040003AAE84DFFCALLnear ptr proc_1 
0050003AD8946FAMOV[bp-6],ax 
0060003B08A46FDMOVal,[bp-3] 
0070003B398CWD  
0080003B450PUSHax 
0090003B5FF76FAPUSHword ptr [bp-6] 
0100003B8E848FFCALLnear ptr proc_2 
0110003BB59POPcx 
0120003BC59POPcx 
0130003BD8946FAMOV[bp-6],ax 
0140003C0FF76FAPUSHword ptr [bp-6] 
0150003C3E8BFFFCALLnear ptr proc_3 
0160003C659POPcx 
0170003C78946FAMOV[bp-6],ax 
0180003CA8B46FAMOVax,[bp-6] 
0190003CD2500FFANDax,0FF00h 
0200003D0B108MOVcl,8 
0210003D2D3E8SHRax,cl 
0220003D48846FEMOV[bp-2],al 
0230003D78A46FAMOVal,[bp-6] 
0240003DA24FFANDal,0FFh 
0250003DC8846FFMOV[bp-1],al 
0260003DFFF76FAPUSHword ptr [bp-6] 
0270003E2B89401MOVax,194h 
0280003E550PUSHax 
0290003E6E8FC08CALLnear ptr printf 
0300003E959POPcx 
0310003EA59POPcx 
0320003EBE80CFFCALLnear ptr proc_1 
0330003EE8946FAMOV[bp-6],ax 
0340003F18A46FDMOVal,[bp-3] 
0350003F498CWD  
0360003F550PUSHax 
0370003F6FF76FAPUSHword ptr [bp-6] 
0380003F9E807FFCALLnear ptr proc_2 
0390003FC59POPcx 
0400003FD59POPcx 
0410003FE8946FAMOV[bp-6],ax 
0420004018A46FEMOVal,[bp-2] 
04300040498CWD  
04400040550PUSHax 
045000406FF76FAPUSHword ptr [bp-6] 
046000409E8F7FECALLnear ptr proc_2 
04700040C59POPcx 
04800040D59POPcx 
04900040E8946FAMOV[bp-6],ax 
0500004118A46FFMOVal,[bp-1] 
05100041498CWD  
05200041550PUSHax 
053000416FF76FAPUSHword ptr [bp-6] 
054000419E8E7FECALLnear ptr proc_2 
05500041C59POPcx 
05600041D59POPcx 
05700041E8946FAMOV[bp-6],ax 
058000421FF76FAPUSHword ptr [bp-6] 
059000424B89A01MOVax,19Ah 
06000042750PUSHax 
061000428E8BA08CALLnear ptr printf 
06200042B59POPcx 
06300042C59POPcx 
06400042D8BE5MOVsp,bp 
06500042F5DPOPbp 
066000430C3RET  
 mainENDP   

图 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文