You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何无法成功调用x86架构中的Call Gate?

问题分析与解决

你的代码存在两个核心问题,直接导致了Bochs中的错误:

  1. 错误将代码段描述符当作调用门使用:call 0b10_0_00:0中的选择符0x10指向的是GDT里的普通代码段描述符,但callf指令通过调用门跳转时,选择符必须指向调用门描述符(系统段描述符的一种),而非普通代码段。
  2. 调用门结构缺失:你未按照调用门的专属格式定义GDT条目,当前第三个GDT条目是代码段格式,不符合调用门的结构要求。

修正后的引导扇区代码

boot equ 0x7C00

lgdt [boot + gdt_info]

mov eax, cr0
or eax, 1
mov cr0, eax

; 调用调用门,选择符0x10指向GDT中的调用门描述符
call 0x10:0

gdt:
; 空描述符
dd 0,           0
; 目标代码段描述符(选择符0x08):基址0x7C00,限长512字节,DPL=0的16位代码段
dd 0x7C0001FF,  0b00000000000000001_00_1101000000000
; 调用门描述符(选择符0x10):目标选择符0x08,偏移0,无参数传递
dw 0x0000,      0x0008    ; 目标偏移低16位、目标代码段选择符
db 0x00,        0b11001110 ; 参数个数0、类型0xE(16位调用门)、DPL=0、存在位P=1
dw 0x0000                  ; 16位模式下目标偏移高16位无用,设为0

gdt_info:
dw 0x17 ; GDT总长度24字节,limit为总长度减一(24-1=23=0x17)
dd boot + gdt

times (510 - ($ - $$)) db 0
db 0x55, 0xAA

关键修正点说明

  • 调用门格式:16位调用门的类型字段固定为0xE,需设置存在位P=1、特权级DPL=0(与当前CPL一致),目标选择符指向你要跳转的代码段(0x08)。
  • 指令调用对象:call 0x10:0中的0x10现在正确指向调用门描述符,CPU会自动解析调用门并跳转到目标代码段的0偏移处。
  • GDT长度验证:三个描述符共24字节,gdt_info中的dw 0x17是正确的总长度减一,避免越界访问错误。

原错误解释

  • bx_dbg_read_pmode_descriptor: selector 0x0010 points to a system descriptor and is not supported!:CPU尝试将普通代码段描述符当作系统段(调用门)解析,格式不匹配导致报错。
  • fetch_raw_descriptor: GDT: index (1007) 200 > limit (17):错误的调用门结构导致CPU计算出非法的GDT索引,触发越界访问异常。

内容的提问来源于stack exchange,提问作者Weg Wang

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 06:15:13