X86

多年以前搞的 8086 实模式模拟器竟然又派上了用场

| Kernel | #x86 | #Emulator | #FreeBSD | #DOS | #Assembly | #汇编 | #模拟器

最近张师傅在折腾一个模拟器,在感慨他老人家的工作不饱和之余, 我向他隆重介绍了我多年前埋到 FreeBSD 里的 x86模拟器

这些代码我自己已经多年没有碰过了,后续也有一些其他开发人员在其上做了新的改进(比如没必要真的分配那么多内存给模拟器, 等等)。不过这份来自 SciTech Software Inc (是的,就是 DOS 时代写 UniVBE.exe 的那个公司),后来辗转经过 XFree86、 NetBSD 最终来到 FreeBSD 的模拟器的主体部分还是没有什么变化,稍微改一改就可以直接作为一个新的模拟器的基础了。 由于不依赖 VM86,它的可移植性要比需要 VM86 的要好很多。从调试方面,由于它的结构,只需要在 x86emu_exec_* 设置断点就可以很容易地在用户态挂调试器进行调试了。

参与评论

一个奇怪的移位计算结果

今天 强迫症 朱小瘦同学提到一个非常有意思的问题,一个32bit的无符号整数算术右移32个bit应该得多少?

我们知道算术右移一个bit相当于除2,所以一个32bit无符号整数除以 2322^{32},理论上,应该得0。

然而事实不是这样。测试显示在 x86 系统上,一个32bit无符号整数算术右移32个bit之后得到的是原数。例如下面这个测试程序:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
#include <stdio.h>

int
main(void /* int argc, char **argv */)
{
	unsigned int a = 0x5a5a5a5a;

	a >>= 32;

	printf("%x\n", a);

	return 0;
}

不启用任何优化的话,编译出来的程序得到的结果是:

5a5a5a5a

更进一步,我们将上面的测试改写为:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
#include <stdio.h>

int
main(void /* int argc, char **argv */)
{
	unsigned int a = 0x5a5a5a5a;
	int i;

	for (i=0; i<33; i++)
		printf("%x\n", a >> i);

	return 0;
}
阅读全文…( 本文约 881 字,阅读大致需要 2 分钟 )

FreeBSD上的{rd,wr}msr_safe

| Kernel | #FreeBSD | #kernel | #assembly | #MSR | #x86

这几天改 FreeBSDcoretemp(4) 遇到了一个问题。直接使用 rdmsr 的话,如果那个 MSR 不存在,则会触发 #GP(0),不了解 CPU 型号的情况下直接去杵肯定是不行的。后来翻了一下 cpuctl(4) 的代码发现 FreeBSD 上也有 rdmsr_safe。它的实现并不复杂( sys/amd64/amd64/support.S):

阅读全文…( 本文约 364 字,阅读大致需要 1 分钟 )