god damn CPU_LOOP 1(done)

本文详细分析了在内核重建中断描述符表(IDT)模块时,出现CPU_LOOP1异常的原因,并提供了解决方法。通过修改内存写操作的循环次数,从8改为16,成功避免了异常发生。

updated 2014-02-18:

CPU_LOOP 1在这里的含义为:写内存异常,因为ds指向了cs属性的代码段,当然,执行如下代码的时候会出现一个异常!

 mov dword ptr ds:[edx], eax

需要将下面:

mov cx, 0x08
改成

mov cx, 0x10

------- history --------

在调试内核重建idt模块的时候,就是一个简单的内存write操作,会出现一个CPU_LOOP 1的异常,目前暂未找到合理的解释和解决办法:

<bochs:14> 
Next at t=5544195
(0) [0x000067d5] 0008:000067d5 (unk. ctxt): mov dword ptr ds:[edx], eax ; 3e8902
<bochs:15> info cpu
eax:0x000867f0, ebx:0x0000000f, ecx:0x000067f0, edx:0x00005093
ebp:0x00009ea8, esp:0x00009ea8, esi:0x00000416, edi:0x0000cf92
eip:0x000067d5, eflags:0x00000006, inhibit_mask:0
cs:s=0x0008, dl=0x0000ffff, dh=0x004f9800, valid=1
ss:s=0x0010, dl=0x00000fff, dh=0x00c09300, valid=7
ds:s=0x0008, dl=0x00000fff, dh=0x00c09a00, valid=1
es:s=0x0010, dl=0x00000fff, dh=0x00c09300, valid=1
fs:s=0x0010, dl=0x00000fff, dh=0x00c09300, valid=1
gs:s=0x0010, dl=0x00000fff, dh=0x00c09300, valid=1
ldtr:s=0x0000, dl=0x00000000, dh=0x00000000, valid=0
tr:s=0x0000, dl=0x00000000, dh=0x00000000, valid=0
gdtr:base=0x00005893, limit=0x7ff
idtr:base=0x00005093, limit=0x7ff
dr0:0x00000000, dr1:0x00000000, dr2:0x00000000
dr3:0x00000000, dr6:0xffff0ff0, dr7:0x00000400
cr0:0x80000011, cr1:0x00000000, cr2:0x00000000
cr3:0x00000000, cr4:0x00000000
done
<bochs:16> n
CPU_LOOP 1
CPU_LOOP 1
CPU_LOOP 1
CPU_LOOP 1
CPU_LOOP 1

<bochs:15> info gdt
Global Descriptor Table (0x00005893):
GDT[0x00]=??? descriptor hi=00000000, lo=00000000
GDT[0x01]=Code segment, linearaddr=00000000, len=00fff * 4Kbytes, Execute/Read, Accessed, 32-bit addrs
GDT[0x02]=Data segment, linearaddr=00000000, len=00fff * 4Kbytes, Read/Write, Accessed
GDT[0x03]=??? descriptor hi=00000000, lo=00000000
GDT[0x04]=??? descriptor hi=00000000, lo=00000000


<bochs:16> 	info idt
Interrupt Descriptor Table (0x00005093):
IDT[0x00]=32-Bit Interrupt Gate target=0x0008:0x000000aa, DPL=0
IDT[0x01]=32-Bit Interrupt Gate target=0x0008:0x000000aa, DPL=0
IDT[0x02]=32-Bit Interrupt Gate target=0x0008:0x000000aa, DPL=0
IDT[0x03]=32-Bit Interrupt Gate target=0x0008:0x000000aa, DPL=0
IDT[0x04]=32-Bit Interrupt Gate target=0x0008:0x000000aa, DPL=0
IDT[0x05]=32-Bit Interrupt Gate target=0x0008:0x000000aa, DPL=0
IDT[0x06]=32-Bit Interrupt Gate target=0x0008:0x000000aa, DPL=0
IDT[0x07]=32-Bit Interrupt Gate target=0x0008:0x000000aa, DPL=0

附上代码snapshot:

;Function:set_trap_gate(eax,bx,edx)
;input:回调入口地址entry_addr(eax),门类型type(bl),dpl(bh),待写入的gate表项的绝对地址gate_addr(edx)
;output: null
;action:将给定的回调入口addr,门类型,dpl拼装成8bytes的gate描述符表项,写入到指定gate_addr
;att:后面的参数先入栈, func protype:	set_gate(entry_addr, TRAP_TYPE, dpl, gate_addr);
;调用栈关系如下
; +-----+
;gate_addr	4bytes edx
;   dpl		4bytes 
;   type	4bytes ebx
; entry_addr	4bytes eax
;  ret_val	4bytes
; old_ebp	4bytes
;          <------------esp
set_gate:
	push ebp
	mov ebp, esp
	mov edx, [esp+20]	;idt gate_addr
	mov ebx, [esp+12]	;type	fixme: 2014-02-15, 4bytes对齐
	mov eax, [esp+8]	;entry_addr
	mov cx, 0x08
	mov ds, cx
	;0.将type放在bl,将dpl放在bh
	mov bh, [esp+16]
	
	;1.eax - 门描述符低4bytes
	mov ecx, eax
	;先掩掉eax的高2bytes,后续存放段选择符01-000
	and eax, 0x0000ffff
	;然后或上对应的段选择符
	or eax, 0x00080000	;fixme: 2014-02-15, 段选择子应该在高2bytes上!Dude
	;首先将门描述符的低4bytes写入到内存中
	mov dword [ds:edx], eax	;eax可以解放出来了, TODO_2014-02-15 写内存出现中断异常?


基于模拟退火的计算器 在线运行 访问run.bcjh.xyz。 先展示下效果 https://pan.quark.cn/s/cc95c98c3760 参见此仓库。 使用方法(本地安装包) 前往Releases · hjenryin/BCJH-Metropolis下载最新 ,解压后输入游戏内校验码即可使用。 配置厨具 已在2.0.0弃用。 直接使用白菜菊花代码,保留高级厨具,新手池厨具可变。 更改迭代次数 如有需要,可以更改 中39行的数字来设置迭代次数。 本地编译 如果在windows平台,需要使用MSBuild编译,并将 改为ANSI编码。 如有条件,强烈建议这种本地运行(运行可加速、可多次重复)。 在 下运行 ,是游戏中的白菜菊花校验码。 编译、运行: - 在根目录新建 文件夹并 至build - - 使用 (linux)(windows) 运行。 最后在命令行就可以得到输出结果了! (注意顺序)(得到厨师-技法,表示对应新手池厨具) 注:linux下不支持多任务选择 云端编译已在2.0.0弃用。 局限性 已知的问题: - 无法得到最优解! 只能得到一个比较好的解,有助于开阔思路。 - 无法选择菜品数量(默认拉满)。 可能有一定门槛。 (这可能有助于防止这类辅助工具的滥用导致分数膨胀? )(你问我为什么不用其他语言写? python一个晚上就写好了,结果因为有涉及json读写很多类型没法推断,jit用不了,算这个太慢了,所以就用c++写了) 工作原理 采用两层模拟退火来最大化总能量。 第一层为三个厨师,其能量用第二层模拟退火来估计。 也就是说,这套方法理论上也能算厨神(只要能够在非常快的时间内,算出一个厨神面板的得分),但是加上厨神的食材限制工作量有点大……以后再说吧。 (...
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值