在第一个 Y86 程序中没有得到输出
Posted
技术标签:
【中文标题】在第一个 Y86 程序中没有得到输出【英文标题】:Not getting output in first Y86 program 【发布时间】:2011-11-07 02:38:14 【问题描述】:我正在努力学习 Y86,所以我做了一个非常简单的程序。它有一个由三个长整数组成的数组,每个块都是通过rdint
询问用户输入来填充的。
compiled(?) 程序要求三个输入,但无法将它们打印出来。
代码:
Main: irmovl Array, %edx
rdint %eax
rmmovl %eax, 0(%edx)
rdint %eax
rmmovl %eax, 4(%edx)
rdint %eax
rmmovl %eax, 8(%edx)
irmovl $10, %edi
Print: irmovl Array, %edx
mrmovl 0(%edx), %eax
wrch %eax
wrch %edi
mrmovl 4(%edx), %eax
wrch %eax
wrch %edi
mrmovl 8(%edx), %eax
wrch %eax
wrch %edi
halt
.align 4
Array:
.long 0
.long 0
.long 0
我的意见:
0
1
2
输出:
(three blank lines below)
Stopped in 22 steps at PC = 0x47. Exception 'HLT', CC Z=1 S=0 O=0
Changes to registers:
%edx: 0x00000000 0x0000004c
%edi: 0x00000000 0x0000000a
Changes to memory:
0x0004: 0x024008f2 0x00000001
0x0008: 0x00000000 0x00000002
Changes to memory: 0x0004: 0x024008f2 0x00000001 0x0008:
0x00000000 0x00000002
【问题讨论】:
【参考方案1】:程序有一个经典问题:ys文件中缺少换行符,导致YAS行为异常。
第一个问题是由于 YAS 中的错误。如果您查看 YAS 生成的 yo 文件,您会发现最后一个 .long 0 语句永远不会被定义。您可能还会看到 yo 文件中的第一行操作码是 0x00,即 nop(当 YAS 遇到没有关联换行符的最终指令时,它会将其环绕,搞砸 yo 文件)
这意味着你丢失了第一个 irmovl 数组,%edx(它变成了某种废话,可能是 0x00000000,即 4 个 nops),所以你写了第一个读取字符 x'30'(ascii 代表 '0')到 edx 指向的位置(可能是 0x00000000,)在第一条指令中(这是 4 个 nops - 请记住,您读取了一个字符,但它最终在一个 4 字节寄存器中并按原样保存。)所以您正在将 0x00000000 写入地址为 0x00000000,这对 YIS 意味着寄存器未更改,因此它未显示在“更改内存”转储部分中。
第二次读取重复此操作,在第二个字中写入 0x00000001(覆盖该位置的指令),第三次读取,在第三个字中写入 0x00000002(覆盖该位置的指令)。
现在,当然,你完全被水洗了!您重置指向数组的指针(使用 edx,)并尝试打印内容,但 Array(0)、Array(4) 和 Array(8) 包含 0x00000000,因为这是您定义的(使用您的 . long 4 语句用于 Array(0) 和 Array(4) 并自动用于 Array(8),因为 Y86 中未定义内存的默认设置是 0x00000000。因此,程序打印 x'00'(因为您打印一个字符来自一个 4 字节的字,)当然是垃圾。
您会注意到这与 YIS 的转储相符。 eax 没有显示,因为它与初始值 0x00000000 没有变化。 edx 和 edi 看起来 A-OK,edi 指向 Array(8)。唯一改变的内存是程序的第二个和第三个字(分别被 0x00000001 和 0x00000002 覆盖)
所以,总而言之。 YAS 犯了一个错误。您必须通过在最后一个 .long 0 语句之后添加一个新行来克服这个问题。 YIS 会误导您,因为关键!当您用数据覆盖代码时,它不会引发异常。
【讨论】:
您没有表明您发布的链接来自您自己的网站,这是必需的。我已经删除了它们,因为它们不是必需的。以上是关于在第一个 Y86 程序中没有得到输出的主要内容,如果未能解决你的问题,请参考以下文章