fix(includes): asm 内联汇编输出占位符/clobber、vipermath 位重解释、string.split 容量参数

- asm.vp: inb/inw/inl 模板引用输出占位符 \ 并补 ~{rax}(原取硬编码 eax 且静默破坏 EAX,对齐 mm.vp cmos_read 模式)

- vipermath.vp: isnan/isinf 改 c.Load 位重解释(原 fptosi 位模式丢失导致恒返回 0)

- string.vp: split 增加 cap 容量参数,token 数 <= cap-1,防止越界写
This commit is contained in:
TermiNexus committed 2026-09-11 14:26:47 +08:00
1 parent 728d090815
commit 52af24e85d
3 files changed
+37 -13

No files matched your search

+11 -6
View File
@@ -18,11 +18,14 @@ def pause():
def inb(port: t.CUInt16T) -> t.CUInt8T:
value: t.CUInt32T
# 模板内必须引用输出占位符 $0(DSL 约定,见 atom.vp),否则输出寄存器由 LLVM
# 任意分配而结果取自硬编码 eax → 读到未定义寄存器;同时 in al,dx 改写 AL,
# 需显式声明 ~{rax} clobber。
c.Asm(f"""mov edx, {c.AsmInp(t.CUInt32T(port), t.ASM_DESCR.REG_ANY)}
in al, dx
movzx eax, al""",
movzx $0, al""",
out = [c.AsmOut(value, t.ASM_DESCR.OUTPUT_REG)],
op =[t.ASM_DESCR.CLOBBER_RDX])
op =[t.ASM_DESCR.CLOBBER_RDX, t.ASM_DESCR.CLOBBER_RAX])
return t.CUInt8T(value)
def outb(port: t.CUInt16T, value: t.CUInt8T):
@@ -36,9 +39,10 @@ def inw(port: t.CUInt16T) -> t.CUInt16T:
value: t.CUInt32T
c.Asm(f"""mov edx, {c.AsmInp(t.CUInt32T(port), t.ASM_DESCR.REG_ANY)}
in ax, dx
movzx eax, ax""",
movzx eax, ax
mov {c.AsmOut(value, t.ASM_DESCR.OUTPUT_REG)}, eax""",
out = [c.AsmOut(value, t.ASM_DESCR.OUTPUT_REG)],
op =[t.ASM_DESCR.CLOBBER_RDX])
op =[t.ASM_DESCR.CLOBBER_RDX, t.ASM_DESCR.CLOBBER_RAX])
return t.CUInt16T(value)
def outw(port: t.CUInt16T, value: t.CUInt16T):
@@ -50,9 +54,10 @@ def outw(port: t.CUInt16T, value: t.CUInt16T):
def inl(port: t.CUInt16T) -> t.CUInt32T:
value: t.CUInt32T
c.Asm(f"""mov edx, {c.AsmInp(t.CUInt32T(port), t.ASM_DESCR.REG_ANY)}
in eax, dx""",
in eax, dx
mov {c.AsmOut(value, t.ASM_DESCR.OUTPUT_REG)}, eax""",
out = [c.AsmOut(value, t.ASM_DESCR.OUTPUT_REG)],
op =[t.ASM_DESCR.CLOBBER_RDX])
op =[t.ASM_DESCR.CLOBBER_RDX, t.ASM_DESCR.CLOBBER_RAX])
return value
def outl(port: t.CUInt16T, value: t.CUInt32T):
+13 -1
View File
@@ -383,17 +383,29 @@ def atof_out(src: str, out: t.CDouble | t.CPtr) -> int:
out[0] = v
return 1
def split(s: str, delim: str, result: t.CArray[str]) -> int:
def split(s: str, delim: str, result: t.CArray[str], cap: int) -> int:
"""按单字符分隔符切分 s,token 指针写入 result[0..],尾部写 None 哨兵。
cap: result 数组的**声明容量**(元素个数)。此前无容量参数 → 写
result[count] 与 result[count]=None 均无上界;token 数超过调用方数组
容量时越界写(devfs 用 t.CArray[str, 256],256 个 token 即写穿 2048 字节)。
现限制 token 数 ≤ cap-1(留一格给结尾哨兵)。
"""
count: int = 0
start: str = s
if not s or not delim or not result:
return 0
if cap <= 0:
return 0
d: t.CChar = delim[0] # 单分隔符
while start[0]:
# 跳过分隔符
while start[0] == d: start += 1
if not start[0]: break
# 容量保护:留最后一格放结尾哨兵
if count >= cap - 1:
break
# 记录token起始
result[count] = start
+13 -6
View File
@@ -526,7 +526,12 @@ class _U(t.CUnion):
u: t.CUInt64T
def isnan(x: t.CDouble) -> t.CStatic | t.CInt:
u: t.CUInt64T = t.CUInt64T(x)
# IEEE-754 位重解释(不能用 t.CUInt64T(x) 数值转换:那是 fptosi,位模式全丢
# → exp_part 恒 0 → 永远返回 0)。用 c.Load 按位拷贝(viperlib
# _check_special_float 同款惯用法)。
xv: t.CDouble = x
u: t.CUInt64T = 0
c.Load(c.Addr(u), c.Addr(xv))
exp_part: t.CUInt64T = (u >> 52) & 0x7FF
mantissa_part: t.CUInt64T = u & 0xFFFFFFFFFFFFF
if exp_part == 0x7FF:
@@ -535,10 +540,12 @@ def isnan(x: t.CDouble) -> t.CStatic | t.CInt:
return 0
def isinf(x: t.CDouble) -> t.CStatic | t.CInt:
u: t.CUInt64T = t.CUInt64T(x)
exp_part: t.CUInt64T = (u >> 52) & 0x7FF
mantissa_part: t.CUInt64T = u & 0xFFFFFFFFFFFFF
if exp_part == 0x7FF:
if mantissa_part == 0:
xv2: t.CDouble = x
u2: t.CUInt64T = 0
c.Load(c.Addr(u2), c.Addr(xv2))
exp_part2: t.CUInt64T = (u2 >> 52) & 0x7FF
mantissa_part2: t.CUInt64T = u2 & 0xFFFFFFFFFFFFF
if exp_part2 == 0x7FF:
if mantissa_part2 == 0:
return 1
return 0