第一次勘误(2011-10-19 01:26:46)
第二次勘误(2011-10-19 18:56:24)
第三次勘误(2011-10-20 23:34:53)
第四次勘误(2011-10-24 21:13:11)
第五次勘误(2011-11-02 19:27:08)
第六次勘误(2011-11-25 12:41:51)
第七次勘误(2011-11-28 15:59:22)
第八次勘误(2012-02-03 16:40:38)
第九次勘误(2012-03-14 20:19:53)
第十次勘误(2012-03-19 00:24:28)
第十一次勘误(2012-03-24 23:08:47)
第十二次勘误(2012-04-20 00:36:02)
第十三次勘误(2014-08-11 05:59:19) 第一章
P9 代码清单1-1上一行 "通过制作SGI文件...",修改为"通过制作SIG文件..."(谢谢网友爱鸟的指正)
第二章
P18 2.1.1小节中的第二段第五行
书中为:"高数据位对高地址,低数据位对低地址"
修改为"低数据位排放在内存的低端,高数据位排放在内存的高端"
P23 第4行 "得到的值为:1.2516582,四舍五入之后为1.3。"
修改为"得到的值为:1.2999999523162841796875,四舍五入之后为1.3。"(感谢网友hexiaomin的指正)
P26 代码清单2-5 倒数第二、三条注释分别修改为 "使用eax保存长整型数据的低4字节,用于返回。" 、"使用edx保存长整型数据的高4字节,用于返回"
P30 2.5.1小节中“向后数4个字节到0x0014FF6C处。将0x0012FF68~0x0014FF6C中的数据按整型存储方式解释。”
修改为“向后数4个字节到0x0012FF6C处。将0x0012FF68~0x0012FF6C中的数据按整型存储方式解释。”(感谢网友fxliutm的指正)
P34 代码清单2-8 “nVarTpye”修改为“nVarType”
P36 2.6.1 代码清单2-10
“#define NUMBER_ONE1”
修改为“#define NUMBER_ONE 1” (感谢网友fishyuule的指正)
P37 代码清单2-12中关于004010B8处的注释:
"; 将地址ebp-4赋值给4字节数据5"
修改为:"; 将地址ebp-4赋值为4字节数据5"(感谢网友二玉的指正)
第三章
P44页,第十行,Enty-Point,应该改成Entry-Point(感谢网友lord的指正)
第四章
P49常量传播 - P50常量折叠 共5处main中的printf函数 "printf("nVarOne = %d \r\n", nVar);"修改为"printf("nVar = %d \r\n", nVar);"
P68 11行"解方程得:o=2^n/c=2^3/38E38E39h=8.999999......"
修改为"解方程得:o=2^n/c=2^33/38E38E39h=8.999999......"(感谢网友孟贤的指正)
P80 "MagicNumber的计算过程在c2文件偏移OX5FACE处"
修改为"MagicNumber的计算过程在c2文件偏移0x5FACE处"(字母O修改为数字0,感谢网友lord的指正)
P104 倒数第13行,“; 对dl做有符号法”,改为“; 对dl做有符号乘法”(感谢网友fxliutm的指正)
P106
; 将edx于0x80000001做位与操作,此操作只会保留下edx的最高位与最低位
; 此操作会影响标记位SF,当edx为负数情况下,则会修改SF标记位
and edx, 80000001h
; 判断SF标记位为0则跳转到标记loc_4010BF处,edx为负数跳转(这里应该是edx为正数跳转)
jns short loc_4010BF
; 以下为edx为负数的处理代码
; edx减等于1,由于之前操作会是edx只保留最低于最高位。
; 这里对edx减1操作,结果必然为0x80000000(或者0x7fffffff,当edx为偶数时)
dec edx
; 对edx与0xFFFFFFFE做位或运算,除最低位外全部置1
; 此时的edx值只有1种可能:0xFFFFFFFE(应该是存在两种可能,另一种是edx为偶数时,其值为0xfffffff)
or edx, 0FFFFFFFEh
; 对edx加1后,变为0xFFFFFFFF为-1(或者为0,当edx为偶数时)
inc edx
; 地址标号
; 这里为IDA标注引用此标号处
loc_4010BF: ; CODE XREF: _main+B8 j
以上代码注释描叙有误,详见括弧内的更正。其实这里是个有符号数求模,原注释过于冗余,应作出如下更正:
; 优化后的求模运算,等价于edx = edx%2,详见前文中对取模运算的讲解
and edx, 80000001h
jns short loc_4010BF
dec edx
or edx, 0FFFFFFFEh
inc edx
loc_4010BF:
P80,第八行,最后的取整符号有误:
(感谢网友kaoyange的指正)
第五章
P117 总结: 标号IF_ELSE_END修改为 ELSE_IF_END
P123页中,代码清单5-12里
; 将加1后的变量放回
0040111C mov dword ptr [ebp-8],edx
修改为:
; 将减1后的变量放回
0040111C mov dword ptr [ebp-8],edx(感谢网友踏雪xp的指正)
P130页,代码清单5-16里:
; 地址0x0040E02F为索引表首地址,查看图5-5
修改为:
; 地址0x0040E02F为索引表首地址,查看图5-7
代码清单5-16里:
; 地址0x0040E013为case语句块地址表首地址。查看图5-5
修改为:
; 地址0x0040E013为case语句块地址表首地址。查看图5-8
(以上感谢网友zpsemo的指正)
P146 代码清单5-26 第一行注释中 "for循环..."修改为"do循环..."
第七章
P169 代码清单7-3 第一行注释中 "全局变量的..."修改为"局部静态变量的..."
第八章
P181 代码清单8-3 反汇编代码提示中的"Hello World"应修改为"Hello Worl"(感谢网友zpsemo的指正)
P183 C++源码对照的GetLen中repne scasb的注释部分:
; 执行该指令后,而ecx中保存了字符串长度的补码
修改为:
; 执行该指令后,而包含了字符串长度相关信息,详细讲解见下文。(感谢网友迪文的指正)
P184 第7行:
neg(ecx(终值))+1=Len+2
修改为:
not(ecx(终值))+1=Len+2 (感谢网友迪文的指正)
P193 图8-8 上方那行"使用下标4也将会..."修改为"使用下标5也将会..."
图8-8的标识"VC 8.0中使用数组下标为负数的..."修改为 "VC 6.0中使用数组下标越界访问"
第九章
P209 如以下代码所示中的 结构体定义关键字 Struct修改为 struct
P215 第一段中"所有成员函数都有一个隐藏参数..."修改为 "所有成员函数(非静态成员函数)都有一个隐藏参数"
P227 "还可以在函数调用过程中避免复制..."修改为 "还可以在函数调用过程中避免复制对象的过程,提升程序运行的效率。"
第十章
P248 代码清单10-9 0040F6D7处的指令"push ffset @ILT+60..."修改为"push offset @ILT+60..."
P251 代码清单10-11 0040170C处的注释"获取堆空间的首地址"修改为"获取第一个对象的首地址"
第十一章
P260 第二段倒数第三句 "this的地址赋值为虚表首地址时..."修改为"this的地址初始化为虚表首地址时..."
P262 代码中
===========================================================
; 调用函数的实现代码内
pop ecx ; this指针的还原,非Debug编译选项组可能无此代码
mov eax, dword ptr [ecx] ; 取出首地址前4字节数据
; 向对象首地址处写入4字节数据,查看并确认此4字节数据是否为函数地址表的首地址
mov dword ptr [reg], XXXXXXXXh
===========================================================
修改为:
===========================================================
; 调用函数的实现代码内
mov reg, this ; 某寄存器得到对象首地址
; 向对象首地址处写入4字节数据,查看并确认此4字节数据是否为函数地址表的首地址
mov dword ptr [reg], XXXXXXXXh
===========================================================
P262 第四段第二行"而且在构造函数中虚表指针没有指向虚表的首地址" 中修改为“而且在构造函数执行前虚表指针没有指向虚表的首地址”
第十二章
P269 第四段第三行 "销售员拿出一款“江斯丹顿牌某系列某型号的..." ,修改为“劳斯丹顿牌某系列某型号的..."
P276代码清单12-5,“virtual void ShowSpeak(){ // 纯虚函数,后面会讲到”,修改为“virtual void ShowSpeak(){ // 这里使用纯虚函数更好,相关知识点后面会讲到”(谢谢网友superzxt的指正)
P295 代码清单12-9下一段中第三行"后调整了父类CSofa的大小...",大小,修改为"后调整了父类CSofa的长度..."
P297 第三段“转换父类指针时,需要跳转到对象的首地址。”,修改为“转换父类指针时,需要调整到对象的首地址。”(感谢网友qqbwz的指正)
P298 标题"12.3 虚基类" 虚基类修改为抽象类
本小节中所有的"虚基类" 需修改为 "抽象类" 、 "CVirtualBase" 需修改为 "CAbstractBase"
第十三章
P340 倒数第一段第一行"首先观察00401180处的注释(上面代码中以下画线)..." 上面代码中以下画线 需修改为 “上面代码中下划线所示”
因此带来的不便,请大家多多包涵,在此谢过。
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!