diff --git a/VKernel/Kernel/execrunner/elf.vp b/VKernel/Kernel/execrunner/elf.vp index d46882d..583c546 100644 --- a/VKernel/Kernel/execrunner/elf.vp +++ b/VKernel/Kernel/execrunner/elf.vp @@ -133,7 +133,11 @@ def load_elf(path: t.CConst | str, do_map: int = 1) -> t.CPtr: # [DIAG] read_len 实际值 + call 后 RAX 快照:区分"call 返回错"(rl=0 rax=0) # vs "store 后 RAX 被覆盖"(rl=0 rax=64) _rax_v2: uint64 = 0 - c.Asm(f"""mov {c.AsmOut(_rax_v2, t.ASM_DESCR.OUTPUT_REG)}, rax""", op=[t.ASM_DESCR.CLOBBER_MEMORY]) + # 读 RAX 未声明输入:至少须声明 CLOBBER_RAX,让编译器知道本块不保留 + # RAX(此前只声明 ~{memory},编译器可假设 RAX 存活 → 读到的值不保证是 + # 紧邻 call 的返回值)。N16。(本块为 [DIAG] 探针,问题定位后建议删除。) + c.Asm(f"""mov {c.AsmOut(_rax_v2, t.ASM_DESCR.OUTPUT_REG)}, rax""", + op=[t.ASM_DESCR.CLOBBER_MEMORY, t.ASM_DESCR.CLOBBER_RAX]) _dbrl: t.CArray[t.CChar, 96] viperlib.snprintf(c.Addr(_dbrl), 96, "[elf] rl=%lu rax=0x%lx\n", read_len, _rax_v2) serial.puts(c.Addr(_dbrl)) @@ -302,9 +306,12 @@ def run_elf(path: t.CConst | str) -> int: serial.puts("[elf] load failed\n") return -1 serial.puts("[elf] jumping to entry...\n") + # 被调方是任意 ELF 入口(外部代码):`call` 破坏全部 caller-saved 寄存器, + # 除 rax/rcx/rdx/r8~r11 外必须声明 rsi/rdi(N20)。 c.Asm(f"""call {c.AsmInp(entry, t.ASM_DESCR.REG_ANY)}""", op=[t.ASM_DESCR.CLOBBER_MEMORY, t.ASM_DESCR.CLOBBER_RAX, t.ASM_DESCR.CLOBBER_RCX, t.ASM_DESCR.CLOBBER_RDX, + t.ASM_DESCR.CLOBBER_RSI, t.ASM_DESCR.CLOBBER_RDI, t.ASM_DESCR.CLOBBER_R8, t.ASM_DESCR.CLOBBER_R9, t.ASM_DESCR.CLOBBER_R10, t.ASM_DESCR.CLOBBER_R11]) serial.puts("[elf] returned from entry\n") diff --git a/VKernel/Kernel/intr/idt.vp b/VKernel/Kernel/intr/idt.vp index 9c76fc6..5d0aabb 100644 --- a/VKernel/Kernel/intr/idt.vp +++ b/VKernel/Kernel/intr/idt.vp @@ -325,6 +325,7 @@ def isr33_handler() -> t.CExport | t.CVoid: c.Asm(f"""call {c.AsmInp(handler, t.ASM_DESCR.REG_ANY)}""", op=[t.ASM_DESCR.CLOBBER_MEMORY, t.ASM_DESCR.CLOBBER_RAX, t.ASM_DESCR.CLOBBER_RCX, t.ASM_DESCR.CLOBBER_RDX, + t.ASM_DESCR.CLOBBER_RSI, t.ASM_DESCR.CLOBBER_RDI, t.ASM_DESCR.CLOBBER_R8, t.ASM_DESCR.CLOBBER_R9, t.ASM_DESCR.CLOBBER_R10, t.ASM_DESCR.CLOBBER_R11]) pic.eoi(1) @@ -336,6 +337,7 @@ def isr34_handler() -> t.CExport | t.CVoid: c.Asm(f"""call {c.AsmInp(handler2, t.ASM_DESCR.REG_ANY)}""", op=[t.ASM_DESCR.CLOBBER_MEMORY, t.ASM_DESCR.CLOBBER_RAX, t.ASM_DESCR.CLOBBER_RCX, t.ASM_DESCR.CLOBBER_RDX, + t.ASM_DESCR.CLOBBER_RSI, t.ASM_DESCR.CLOBBER_RDI, t.ASM_DESCR.CLOBBER_R8, t.ASM_DESCR.CLOBBER_R9, t.ASM_DESCR.CLOBBER_R10, t.ASM_DESCR.CLOBBER_R11]) pic.eoi(2) @@ -347,6 +349,7 @@ def isr35_handler() -> t.CExport | t.CVoid: c.Asm(f"""call {c.AsmInp(handler3, t.ASM_DESCR.REG_ANY)}""", op=[t.ASM_DESCR.CLOBBER_MEMORY, t.ASM_DESCR.CLOBBER_RAX, t.ASM_DESCR.CLOBBER_RCX, t.ASM_DESCR.CLOBBER_RDX, + t.ASM_DESCR.CLOBBER_RSI, t.ASM_DESCR.CLOBBER_RDI, t.ASM_DESCR.CLOBBER_R8, t.ASM_DESCR.CLOBBER_R9, t.ASM_DESCR.CLOBBER_R10, t.ASM_DESCR.CLOBBER_R11]) pic.eoi(3) @@ -358,6 +361,7 @@ def isr36_handler() -> t.CExport | t.CVoid: c.Asm(f"""call {c.AsmInp(handler4, t.ASM_DESCR.REG_ANY)}""", op=[t.ASM_DESCR.CLOBBER_MEMORY, t.ASM_DESCR.CLOBBER_RAX, t.ASM_DESCR.CLOBBER_RCX, t.ASM_DESCR.CLOBBER_RDX, + t.ASM_DESCR.CLOBBER_RSI, t.ASM_DESCR.CLOBBER_RDI, t.ASM_DESCR.CLOBBER_R8, t.ASM_DESCR.CLOBBER_R9, t.ASM_DESCR.CLOBBER_R10, t.ASM_DESCR.CLOBBER_R11]) pic.eoi(4) @@ -369,6 +373,7 @@ def isr37_handler() -> t.CExport | t.CVoid: c.Asm(f"""call {c.AsmInp(handler5, t.ASM_DESCR.REG_ANY)}""", op=[t.ASM_DESCR.CLOBBER_MEMORY, t.ASM_DESCR.CLOBBER_RAX, t.ASM_DESCR.CLOBBER_RCX, t.ASM_DESCR.CLOBBER_RDX, + t.ASM_DESCR.CLOBBER_RSI, t.ASM_DESCR.CLOBBER_RDI, t.ASM_DESCR.CLOBBER_R8, t.ASM_DESCR.CLOBBER_R9, t.ASM_DESCR.CLOBBER_R10, t.ASM_DESCR.CLOBBER_R11]) pic.eoi(5) @@ -380,6 +385,7 @@ def isr38_handler() -> t.CExport | t.CVoid: c.Asm(f"""call {c.AsmInp(handler6, t.ASM_DESCR.REG_ANY)}""", op=[t.ASM_DESCR.CLOBBER_MEMORY, t.ASM_DESCR.CLOBBER_RAX, t.ASM_DESCR.CLOBBER_RCX, t.ASM_DESCR.CLOBBER_RDX, + t.ASM_DESCR.CLOBBER_RSI, t.ASM_DESCR.CLOBBER_RDI, t.ASM_DESCR.CLOBBER_R8, t.ASM_DESCR.CLOBBER_R9, t.ASM_DESCR.CLOBBER_R10, t.ASM_DESCR.CLOBBER_R11]) pic.eoi(6) @@ -393,6 +399,7 @@ def isr39_handler() -> t.CExport | t.CVoid: c.Asm(f"""call {c.AsmInp(handler7, t.ASM_DESCR.REG_ANY)}""", op=[t.ASM_DESCR.CLOBBER_MEMORY, t.ASM_DESCR.CLOBBER_RAX, t.ASM_DESCR.CLOBBER_RCX, t.ASM_DESCR.CLOBBER_RDX, + t.ASM_DESCR.CLOBBER_RSI, t.ASM_DESCR.CLOBBER_RDI, t.ASM_DESCR.CLOBBER_R8, t.ASM_DESCR.CLOBBER_R9, t.ASM_DESCR.CLOBBER_R10, t.ASM_DESCR.CLOBBER_R11]) pic.eoi(7) @@ -404,6 +411,7 @@ def isr40_handler() -> t.CExport | t.CVoid: c.Asm(f"""call {c.AsmInp(handler8, t.ASM_DESCR.REG_ANY)}""", op=[t.ASM_DESCR.CLOBBER_MEMORY, t.ASM_DESCR.CLOBBER_RAX, t.ASM_DESCR.CLOBBER_RCX, t.ASM_DESCR.CLOBBER_RDX, + t.ASM_DESCR.CLOBBER_RSI, t.ASM_DESCR.CLOBBER_RDI, t.ASM_DESCR.CLOBBER_R8, t.ASM_DESCR.CLOBBER_R9, t.ASM_DESCR.CLOBBER_R10, t.ASM_DESCR.CLOBBER_R11]) pic.eoi(8) @@ -415,6 +423,7 @@ def isr41_handler() -> t.CExport | t.CVoid: c.Asm(f"""call {c.AsmInp(handler9, t.ASM_DESCR.REG_ANY)}""", op=[t.ASM_DESCR.CLOBBER_MEMORY, t.ASM_DESCR.CLOBBER_RAX, t.ASM_DESCR.CLOBBER_RCX, t.ASM_DESCR.CLOBBER_RDX, + t.ASM_DESCR.CLOBBER_RSI, t.ASM_DESCR.CLOBBER_RDI, t.ASM_DESCR.CLOBBER_R8, t.ASM_DESCR.CLOBBER_R9, t.ASM_DESCR.CLOBBER_R10, t.ASM_DESCR.CLOBBER_R11]) pic.eoi(9) @@ -426,6 +435,7 @@ def isr42_handler() -> t.CExport | t.CVoid: c.Asm(f"""call {c.AsmInp(handler10, t.ASM_DESCR.REG_ANY)}""", op=[t.ASM_DESCR.CLOBBER_MEMORY, t.ASM_DESCR.CLOBBER_RAX, t.ASM_DESCR.CLOBBER_RCX, t.ASM_DESCR.CLOBBER_RDX, + t.ASM_DESCR.CLOBBER_RSI, t.ASM_DESCR.CLOBBER_RDI, t.ASM_DESCR.CLOBBER_R8, t.ASM_DESCR.CLOBBER_R9, t.ASM_DESCR.CLOBBER_R10, t.ASM_DESCR.CLOBBER_R11]) pic.eoi(10) @@ -437,6 +447,7 @@ def isr43_handler() -> t.CExport | t.CVoid: c.Asm(f"""call {c.AsmInp(handler11, t.ASM_DESCR.REG_ANY)}""", op=[t.ASM_DESCR.CLOBBER_MEMORY, t.ASM_DESCR.CLOBBER_RAX, t.ASM_DESCR.CLOBBER_RCX, t.ASM_DESCR.CLOBBER_RDX, + t.ASM_DESCR.CLOBBER_RSI, t.ASM_DESCR.CLOBBER_RDI, t.ASM_DESCR.CLOBBER_R8, t.ASM_DESCR.CLOBBER_R9, t.ASM_DESCR.CLOBBER_R10, t.ASM_DESCR.CLOBBER_R11]) pic.eoi(11) @@ -447,6 +458,7 @@ def isr44_handler() -> t.CExport | t.CVoid: c.Asm(f"""call {c.AsmInp(handler, t.ASM_DESCR.REG_ANY)}""", op=[t.ASM_DESCR.CLOBBER_MEMORY, t.ASM_DESCR.CLOBBER_RAX, t.ASM_DESCR.CLOBBER_RCX, t.ASM_DESCR.CLOBBER_RDX, + t.ASM_DESCR.CLOBBER_RSI, t.ASM_DESCR.CLOBBER_RDI, t.ASM_DESCR.CLOBBER_R8, t.ASM_DESCR.CLOBBER_R9, t.ASM_DESCR.CLOBBER_R10, t.ASM_DESCR.CLOBBER_R11]) pic.eoi(12) diff --git a/VKernel/Kernel/paging/paging.vp b/VKernel/Kernel/paging/paging.vp index a95b3c7..d2656c4 100644 --- a/VKernel/Kernel/paging/paging.vp +++ b/VKernel/Kernel/paging/paging.vp @@ -65,11 +65,14 @@ def AllocPage() -> t.CPtr: if pt_pool_used >= uint64(PT_POOL_PAGES): return None page: t.CPtr = t.CVoid(pt_pool_start + pt_pool_used * uint64(4096), t.CPtr) pt_pool_used = pt_pool_used + uint64(1) + # rep stosb 向 [rdi] 写 4096 字节:必须声明 CLOBBER_MEMORY,否则优化器 + # 无法得知本块改写了内存,可能把其前后的内存读写重排/消除(N8)。 c.Asm(f"""mov al, 0 mov ecx, 4096 mov rdi, {c.AsmInp(page, t.ASM_DESCR.REG_ANY)} rep stosb""", - op = [t.ASM_DESCR.CLOBBER_AL, t.ASM_DESCR.CLOBBER_ECX, t.ASM_DESCR.CLOBBER_RDI]) + op = [t.ASM_DESCR.CLOBBER_MEMORY, t.ASM_DESCR.CLOBBER_AL, + t.ASM_DESCR.CLOBBER_ECX, t.ASM_DESCR.CLOBBER_RDI]) AllocatedPages = AllocatedPages + uint64(1) return page diff --git a/VKernel/Kernel/sched/coroutine.vp b/VKernel/Kernel/sched/coroutine.vp index f671013..95de49a 100644 --- a/VKernel/Kernel/sched/coroutine.vp +++ b/VKernel/Kernel/sched/coroutine.vp @@ -197,8 +197,12 @@ def _coro_entry(): mov dword ptr [rax + rcx + 40], 3 mov dword ptr [rax + rcx + 56], eax add rsp, 8""", + # `call rax` 破坏全部 caller-saved 寄存器(x64 SysV):除 RAX/RCX/RDX/ + # R8-R11 外,RSI 与 RDI 也必须声明,否则编译器可能假设其值存活(N9)。 + # RSP 由 `sub rsp,8` / `add rsp,8` 配对抵消,净变化为 0,无需声明。 op=[t.ASM_DESCR.CLOBBER_MEMORY, t.ASM_DESCR.CLOBBER_RAX, t.ASM_DESCR.CLOBBER_RCX, t.ASM_DESCR.CLOBBER_RDX, + t.ASM_DESCR.CLOBBER_RSI, t.ASM_DESCR.CLOBBER_RDI, t.ASM_DESCR.CLOBBER_R8, t.ASM_DESCR.CLOBBER_R9, t.ASM_DESCR.CLOBBER_R10, t.ASM_DESCR.CLOBBER_R11]) Coroutine._yield() diff --git a/VKernel/Kernel/sched/process.vp b/VKernel/Kernel/sched/process.vp index 669241a..add8276 100644 --- a/VKernel/Kernel/sched/process.vp +++ b/VKernel/Kernel/sched/process.vp @@ -190,7 +190,7 @@ class ProcessManager: for j in range(PROC_MAX_DIRS): p.dir_used[j] = 0 p.dir_table[j] = t.CVoid(0, t.CPtr) - ks: t.CPtr = mm_mm.malloc(KERN_STACK_SIZE) + ks: t.CPtr = mm.malloc(KERN_STACK_SIZE) # [DIAG] 定位跨模块 malloc 返回值(mm 成功但调用方收到 None) _dbg_ks: t.CArray[t.CChar, 64] viperlib.snprintf(c.Addr(_dbg_ks), 64, "[proc] ks=0x%lx\n", uint64(ks)) @@ -201,14 +201,14 @@ class ProcessManager: return None ks_size: uint64 = KERN_STACK_SIZE p.kern_stack = uint64(ks) + ks_size - us: t.CPtr = mm_mm.malloc(USER_STACK_SIZE) + us: t.CPtr = mm.malloc(USER_STACK_SIZE) # [DIAG] 定位 user_stack 收到 None(mm 内部打印成功但此处收 0x0) _dbg_us: t.CArray[t.CChar, 64] viperlib.snprintf(c.Addr(_dbg_us), 64, "[proc] us=0x%lx\n", uint64(us)) serial.puts(c.Addr(_dbg_us)) if us is None: serial.puts("[process] user stack alloc failed\n") - mm_mm.free(ks) + mm.free(ks) m.count = m.count - 1 return None us_size: uint64 = USER_STACK_SIZE diff --git a/VKernel/Kernel/sched/sched.vp b/VKernel/Kernel/sched/sched.vp index 12f34de..3a40514 100644 --- a/VKernel/Kernel/sched/sched.vp +++ b/VKernel/Kernel/sched/sched.vp @@ -278,8 +278,12 @@ def _thread_entry(): imul rcx, rcx, 56 mov dword ptr [rax + rcx + 40], 3 add rsp, 8""", + # `call rax` 破坏全部 caller-saved 寄存器(x64 SysV):除 RAX/RCX/RDX/ + # R8-R11 外,RSI 与 RDI 也必须声明,否则编译器可能假设其值存活(N9)。 + # RSP 由 `sub rsp,8` / `add rsp,8` 配对抵消,净变化为 0,无需声明。 op=[t.ASM_DESCR.CLOBBER_MEMORY, t.ASM_DESCR.CLOBBER_RAX, t.ASM_DESCR.CLOBBER_RCX, t.ASM_DESCR.CLOBBER_RDX, + t.ASM_DESCR.CLOBBER_RSI, t.ASM_DESCR.CLOBBER_RDI, t.ASM_DESCR.CLOBBER_R8, t.ASM_DESCR.CLOBBER_R9, t.ASM_DESCR.CLOBBER_R10, t.ASM_DESCR.CLOBBER_R11]) Scheduler._yield()