【问题标题】:Simple y86 do-nothing program halt简单的 y86 无操作程序停止
【发布时间】:2025-11-24 04:35:01
【问题描述】:
[终端]$ ./yis a.yo 在 PC = 0x2c 时以 11 步停止。状态“HLT”,CC Z=1 S=0 O=0 寄存器变化: %eax: 0x00000000 0x00000004 %ebx: 0x00000000 0x00000005 %esp: 0x00000000 0x00000023 %ebp: 0x00000000 0x0000002f 内存变化: 0x0020: 0x2c803fa0 0x27803fa0 0x0024: 0x20000000 0x05000000 0x0028: 0x905fb054 0x04000000 0x002c: 0x45205fa0 0x37000000 0x0030: 0x32200120 0x0d000000 0x0034: 0x00905fb0 0x00000000 [终端]$ cat a.yo 0x000:| .pos 0 0x000:|在里面: 0x000: 30f437000000 | irmovl 堆栈,%esp 0x006: 2045 | rrmovl %esp, %ebp 0x008: 800e000000 |调用主 0x00d: 00 |停 | 0x00e:|主要的: 0x00e:a05f |推%ebp 0x010: 2045 | rrmovl %esp,%ebp | 0x012: 30f004000000 | irmovl $4,%eax 0x018:a00f | pushl %eax 0x01a:30f305000000 | irmovl $5,%ebx 0x020:a03f |推%ebx 0x022: 802c000000 |调用总和 | 0x027: 2054 | rrmovl %ebp,%esp 0x029: b05f |流行 %ebp 0x02b:90 | ret | 0x02c:|和: 0x02c:a05f | pushl %ebp #就在这里 0x02e: 2045 | rrmovl %esp,%ebp | 0x030: 2001 | rrmovl %eax,%ecx 0x032: 2032 | rrmovl %ebx,%edx | 0x034: b05f |流行 %ebp 0x036: 90 | ret 0x037:|堆:

我正在使用the yas simulator 来编译和运行我的 y86 程序集。我试图理解为什么程序会在 0x2c 处停止,除了将 2 个常量发送到一个函数(甚至没有使用)之外,它什么都不做,只是将作为参数的值移动到其他寄存器中。

【问题讨论】:

    标签: assembly y86


    【解决方案1】:

    您正在用堆栈内容覆盖部分代码。

    您将esp 初始化为Stack,即0x37。当您到达Sum 时,堆栈上将有 5 个 DWORD(3 * pushl 和 2 * call)。五个 DWORD 为 20 字节 (0x14),0x37 - 0x14 为 0x23(请记住,堆栈在内存中向后增长)。您可以看到这是“对寄存器的更改”列表:%esp: 0x00000000 0x00000023

    正如您在“内存更改”列表中所见,位于 0x2C(Sum 开始的位置)的 DWORD 已从 0x45205fa0 更改为 0x37000000。假设 little-endian,这意味着地址 0x2C 处的字节为 0x00,等于HALT

    【讨论】:

    • 那么,我该如何解决这个问题呢?我需要修改 .yo 文件吗?或者我在 .ys 文件中的说明错误(在 | 十六进制说明右侧显示的部分),我已经编译得到这个 .yo 文件?
    • 我不熟悉 Y86 模拟器及其内存映射的样子,但我建议要么将堆栈进一步向前移动(将 esp 初始化为 0x200 之类的东西),要么保持堆栈在它所在的位置并将您的代码向前移动。
    • 为了确定,把irmovl Stack, %esp改成irmovl $512, %esp?
    • 是的,类似的。
    • 我最后在Stack: 之前做了一个.pos 512,谢谢agian