Round 27: a correctly placed first action still does not run; the fitting variable is code size

The game's app_main was given a fill-every-byte-and-blit first act. Inserted before A = api; it dereferenced an unset pointer and faulted (my own bug, that run is void); moved after the assignment (source +199 B, app 2508 B) the panel still never leaves 43 over 48 s, so the blit never happens, while a 300-byte app doing the same fill-and-blit paints 596 non-zero bytes.

The variable that fits every measurement is the app's code size rather than its blob size: a 3028-byte blob with a few dozen bytes of code runs and can call print_tiny, display_clear and get_key; Phases at 372 bytes of code runs; Ladder at 544 dies; Minesweeper at 2400+ dies with its first instruction having no effect. Next: sweep a trivial app at 400, 512, 600, 800 and 1200 bytes of code through the handover to find where the panel stops changing.
This commit is contained in:
mckero committed 2026-10-02 11:54:33 +08:00
1 parent 82a34fe39a
commit cad35e85dd
2 files changed
+42

No files matched your search

+23
View File
@@ -1060,6 +1060,29 @@ whoever clicks through the page: whatever row the cursor lands on, MENU starts t
launching the game and getting out of it -- are now the things to measure next, along with why the app returns
instead of staying up (round 17 saw it paint a full frame from this same artifact).
**Round 27: an app's first action, placed correctly, still does not run -- and the pattern that fits is code size.**
The user's screenshot is the state this file already describes: the app menu's title (drawn in the 8-bit font,
so F4HWN reads as F4HHH) over one blank white box, which is the launcher's own frame with nothing of the app
on the glass.
To separate "the app is not entered" from "the app draws nothing", the game's app_main was given an
unmistakable first act: fill every framebuffer byte with 0xFF and blit. The first attempt inserted it before
`A = api;`, so it dereferenced an unset pointer and faulted -- my own bug, and it invalidated that run. Moved
after the assignment (source +199 bytes, app 2508 bytes) the panel still never leaves 43 over 48 s, so the
probe's blit never happens. A 300-byte app doing exactly that fill-and-blit does paint (596 non-zero bytes),
and the loader has been seen reading the header and exactly code_size bytes.
Taking every measurement together, the variable that fits is the app's **code** size rather than its blob
size: a 3028-byte blob whose code is a few dozen bytes runs and can call print_tiny, display_clear and
get_key; Phases at 372 bytes of code runs; Ladder at 544 bytes dies; Minesweeper at 2400+ bytes dies with
its first instruction having no effect. Round 8's ladder said the same thing and was set aside because a
big blob that calls nothing survived -- which only shows that blob size alone is not the limit.
So the next round has a quantitative target: build the same trivial app with a code body of 400, 512, 600,
800 and 1200 bytes, drive each through the handover, and find where the panel stops changing. That is a
ladder in the one variable that has not been swept.
That is where the next round starts: the same alternating-spin shape, one call at a time.
trace. That is a much better place to be than the emulator mystery this started as.
+19
View File
@@ -858,6 +858,25 @@ PC 追踪**跨过交接点**采样,而不是在它之后。
启动游戏。接下来要量的两件事是「启动游戏」与「从游戏里出来」,以及**它为什么退回来而不是留在上面**(第 17 轮用同一份产物
量到过它画出完整一帧)。
**第 27 轮:把应用的第一个动作放对位置之后它仍然不执行 —— 而能解释一切的模式是「代码量」。**
用户那张截图正是本文件已经描述过的状态:应用菜单的标题(8 位像素字体,于是 F4HWN 看起来像 F4HHH)下面是一整块
空白白框 —— 那是启动器自己的画面,玻璃上没有任何属于应用的东西。
为了把「应用没被进入」与「应用什么都没画」分开,给游戏的 app_main 加了一个无法误认的第一个动作:把每个帧缓冲
字节填成 0xFF 再 blit。第一次插在了 `A = api;` **之前**,于是解引用了一个未设置的指针并崩溃 —— 这是我自己的
bug,也让那次运行作废。改到赋值之后(源码 +199 字节、应用 2508 字节),面板在 48 秒里始终停在 43,说明探针的
blit **从未发生**。而一个 300 字节的应用做**同样**的填满加 blit 是能画的(596 个非零字节),加载器也已被看到读出
头部与恰好 code_size 字节。
把所有测量放在一起,能对上的变量是应用的**代码量**,而不是 blob 大小:一个 3028 字节、代码只有几十字节的 blob
能跑、还能调用 print_tiny、display_clear、get_key;Phases 的代码 372 字节能跑;Ladder 的 544 字节死;Minesweeper
的 2400+ 字节死,而且它的第一条指令毫无效果。第 8 轮那份阶梯说的也是同一件事,当时因为「一个很大的、什么都不调用
的 blob 活着」而被搁置 —— 而那只能说明**blob 大小本身不是限制**。
所以下一轮有了一个定量的目标:用同一个平凡应用做出代码体 400、512、600、800、1200 字节的版本,一个个走过交接点,
找出屏幕在哪一档开始不再变化。这是在**唯一还没被扫过的那个变量**上做阶梯。
下一轮就从这里开始:同样的「自旋 + 单调用」形状,一次只放一个调用。
进去、读同一份 trace。比起一开始那个模拟器悬案,这是好得多的处境。