没有放在程序结束处,而是放在的代码段的起始位置,更甚,由于程序是从start开始执行的,似乎永远不会执行到这两行,程序也永远不会结束。但是这个程序却能正常结束,而且是由我们的这两行代码来结束执行的。
其中的猫腻就在于短转移指令jmp short s1。jmp指令是用来更改寄存器CS:IP来实现程序的转移的,汇编语言中一般是以标号来指明跳转的目的地址的。对于长转移指令,例如jmp dword ptr ds:[0],CPU确实是以目标地址的段基址和段内偏移来修改CS:IP的。但是对于短转移来说,却是利用当前IP与目标地址之间的的偏移量来确定的。上例中,执行jmp short s1时,IP指向下一条指令nop,与目标地址s1之间偏移量为10:

   CS:IP     机器码             汇编指令(编译器将标号替换了)
0B80:0018 B80000        MOV     AX,0000    ;s1
0B80:001B CD21          INT     21
0B80:001D B80000        MOV     AX,0000
0B80:0020 EBF6          JMP     0018           ; jmp short s1
0B80:0022 90              NOP
Tags: ,,.
1
2
3
4
5
//~ 判断字符c是否为空白符(空格、水平制表、垂直制表、换页、回车和换行符)
int my_isspace( int ch )
{
    return (unsigned int)(ch - 9) < 5u  ||  ch == ' ';
}
Tags: .
1
2
3
4
5
6
7
8
9
10
#include <iostream>
using namespace std;
 
int
main()
{
	Derived * pD = new Derived;
	pD->foo();
	return 0;
}
Tags: ,.

函数调用时,调用者依次把参数压栈,然后调用函数,函数被调用以后,在堆栈中取得数据,并进行计算。函数计算结束以后,或者调用者、或者函数本身修改堆栈,使堆栈恢复原装。 在参数传递过程中需要解决两个问题:

  • 当参数大于一个时,参数的入栈顺序如何,即:从右向左亦或是由右向左。
  • 恢复堆栈的任务是由调用函数完成,还是被调用者负责。
Tags: ,,.

windows中的visual studio固然强大,但是对于平时测试用的小程序来说,建立一个工程毕竟是麻烦的。相对来说用g++在命令行下进行编译就方便多了(当然也可以用cl.exe),找到了这么一个工具,cygwin-b20,比较小巧实用。从这里下载
安装及使用方法:
直接使用可执行文件full.exe进行安装,安装目录建议选择默认路径。安装完成后,将路径C:\cygnus\cygwin-b20\H-i586-cygwin32\bin加入的系统环境变量PATH中,这样,你可以在任何目录下执行bin/的命令,其中包含了169个较为常用的linux命令

Tags: ,,,.
1
2
3
4
5
6
7
8
9
class quick_sort
{
public:
	typedef int T;
	explicit quick_sort(T* src, int beg, int end);
private:
	void sub_sort(int beg, int end);
	T* m_src;
};
Tags: ,.

分别演示了冒泡排序和快速排序。最有意思的是里面的机器人,神态相当的可笑!

Tags: ,.

boost目前的最新版本是1.39,下载地址:
http://sourceforge.net/project/showfiles.php?group_id=7586&package_id=8041

下载后,解压boost_1_39_0.tar.gz

1
$ tar -zxvf boost_1_39_0.tar.gz

然后进入解压缩后的文件夹编译boost的编译器jam

1
2
$ cd boost_1_39_0\tools\jam
$ ./build_dist.sh
Tags: ,.
1
2
3
4
5
6
7
8
9
10
#include <iostream>
#include <iomanip>
//~ #include <sqlite.h>
//~ #include <mysql/mysql.h>
using namespace std;
template <unsigned int x, unsigned int y, bool is_ordered = (x >= y)> //~ 一般情况下x>=y
struct static_gcd 
{ 
    static int const value = static_gcd<y, x % y>::value; 
};
Tags: ,.

class D
这里面有三张函数表,分别对应d的三个基类。事实上,d的虚函数d()的地址保存在了基类B1对应的虚函数表内。从多重继承的内存布局,我们可以看到子类新加入的虚函数被加到了第一个基类的虚函数表,所以当dynamic_cast的时候,子类和第一个基类的地址相同,不需要移动指针,但是当dynamic_cast到其他的父类的时候,需要做相应的指针的移动。

Tags: ,.