-3

我试图理解这段代码,以便将其转换为 y86 程序集。有人可以回答括号里写的问题吗?

/* This function copy_block - Copy src to dest and return xor checksum of src */
long copy_block(long *src, long *dest, long len) //(first two input arguments will be stored in %RDI and %RSI where will the be third argument stored?)
{
    long result = 0;
    while (len > 0) {
    long val = *src++; //(is this dereferencing first and then adding or opposite?)
    *dest++ = val; //(what is this line doing?)
    result ^= val; //(what is checksum and why are we XORing val with sum of previous XORed values?)
    len--;
    }
    return result;
}

样本输入

.align 8
# Source block
src:
.quad 0x00a
.quad 0x0b0 
.quad 0xc00
# Destination block
dest:
.quad 0x111  #(why are there three sources and just one dest?)
4

2 回答 2

2

Y86 不是一个“真正的”架构,我相信它是为教育目的而设计的。我在这里找到了对它的引用。它似乎确实使用了 AT&T 语法(即源、目标操作数顺序)。

前两个输入参数将存储在 %RDI 和 %RSI 中,第三个参数将存储在哪里?

检查 Y86 ABI,可能在您的讲义中。如果它与SYSV AMD64 ABI匹配,它将是rdx寄存器(参见表中的最后一行)。

如果你有一个生成 Y86 程序集的 C 编译器,那么编写一个简单的程序,它接受三个参数,并返回一个简单的组合——比如,三个整数相加并返回结果。然后查看哪些寄存器用于产生结果。

long val = *src++;
*dest++ = val;

后增量发生在计算表达式之后。所以,以上等价于

long val = *src;
src++;

*dest = val;
dest++;

什么是校验和?

它是一个用于检测由于传输错误或类似原因导致的数据块变化的少量数字。有关详细信息,请参阅有关校验和的 Wikipedia 文章。

为什么我们要对 val 与先前 XORed 值的总和进行 XORing?

有许多不同的方法来计算校验和;这种特殊的方式是使用 XOR 计算的。

为简单起见,可能选择了 XOR。现实世界的校验和算法使用查找表或位移、XOR 以及(无符号模)加法和乘法。这些将涉及更多的工作来手工转换为组装。

使用校验和的想法是您发送或存储一大块数据和校验和。然后接收者或阅读者可以重新计算校验和,并将其与存储的校验和进行比较。如果两个校验和不同,则数据可能有错误。

校验和并非万无一失。很可能有很多错误,尽管两者明显不同,但它们的校验和匹配。

校验和也不能识别错误的位置或内容。错误识别“校验和”更恰当地称为纠错码。它们通常用于例如 CD、DVD 和蓝光媒体;大多数硬盘驱动器还在内部维护它们写入的数据的校验和,以便在读取数据时可以检测到错误。有关校验和和纠错码的更多信息,请参阅有关错误检测和纠正的 Wikipedia 文章。

为什么有三个来源而只有一个目标?

len该函数将四边形从复制srcdest,因此源和目标的长度应该相等。

示例输入可能是一个错误,但我认为更有可能在您的讲义中提到了示例输入后面有足够数量的未定义字节,即最终标签后面的四边形数量是不表示任何东西。换句话说,讲师/助教/任何人都可以提供样本输入

    .align 8

# Source block
src:
    .quad 0x00a
    .quad 0x0b0 
    .quad 0xc00

 # Destination block
 dest:

因为目的地的内容无论如何都会被覆盖,其内容无关紧要。Y86 程序集似乎不支持.quad ?指令之类的东西,这会使内存保留清晰。

于 2016-10-29T14:07:25.357 回答
-1
  1. (前两个输入参数将存储在 %RDI 和 %RSI 中,第三个参数将存储在哪里?)

%rdx

  1. //(这是先取消引用然后添加还是相反?)

val 设置为存储在 src 中的地址处的值。然后 src 中的地址加一。

  1. //(这条线在做什么?)

val 写入存储在 dst 中的地址,然后 dst 地址加 1。

  1. //(什么是校验和,为什么我们将 val 与先前 XORed 值的总和进行 XORing?)

此校验和是检测块更改的原始方法。例如,如果您随后将数据传输到某个地方,并再次处理校验和,如果块数据发生了变化,则校验和很可能已经发生了变化。因此,如果您将校验和与块一起发送,并且其中任何一个发生了更改,它们将不再匹配(计算出的校验和将与发送的校验和不匹配)。这通常在通过 RS232 等串行 com 发送数据时使用。

于 2016-10-29T13:47:56.437 回答