我试图理解此代码,以将其转换为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?)
最佳答案
我认为,Y86不是一种“真实”的体系结构,而是为教育目的而设计的。我找到了对它的引用here。它似乎确实使用了AT&T语法(即源,目标操作数顺序)。
前两个输入参数将存储在%RDI和%RSI中,第三个参数将存储在哪里?
检查Y86 ABI,可能在您的讲义中。如果与SYSV AMD64 ABI匹配,则为rdx
寄存器(请参阅表的最后一行)。
如果您有一个生成Y86程序集的C编译器,请编写一个包含三个参数的简单程序,并返回一个简单的组合-例如,将三个int求和在一起并返回结果。然后查看哪些寄存器用于产生结果。
long val = *src++;
*dest++ = val;
后递增发生在对表达式求值之后。所以,以上等同于
long val = *src;
src++;
和
*dest = val;
dest++;
什么是校验和?
它是用于检测由于传输错误或类似原因而导致的数据块变化的一小部分。有关详细信息,请参见checksum上的Wikipedia文章。
为什么我们将val与先前的XORed值之和进行XORing?
有许多不同的方法来计算校验和。这种特殊的方式是使用XOR计算的。
为简单起见,可能选择了XOR。现实世界中的校验和算法使用查找表或移位,XOR和(无符号模)加法和乘法。这些将需要更多的工作才能手工转换为汇编。
使用校验和时,您可以发送或存储大块数据以及校验和。然后,接收者或阅读者可以重新计算校验和,并将其与存储的校验和进行比较。如果两个校验和不同,则数据可能有错误。
校验和不是万无一失的。可能有这么多错误,尽管两者明显不同,但是它们的校验和却匹配。
校验和也不能识别错误的位置或原因。标识错误的“校验和”更恰当地称为错误校正码。它们通常用于例如CD,DVD和Blu-ray媒体;大多数硬盘驱动器还在内部维护已写入数据的校验和,以便它们在回读时可以检测到错误。有关校验和和纠错码的更多信息,请参见Error detection and correction上的Wikipedia文章。
为什么有三个来源而只有一个目的地?
该函数将
len
四边形从src
复制到dest
,因此源和目标的长度应相等。样本输入可能是一个错误,但我认为您的讲义中的某个地方更可能提到样本输入被假定为跟随有足够数量的未定义字节,即,最终标签后面的四边形数量为没有任何指示。换句话说,讲师/助教/任何人都可以提供与
.align 8
# Source block
src:
.quad 0x00a
.quad 0x0b0
.quad 0xc00
# Destination block
dest:
因为目的地的内容无论如何都会被覆盖,并且它的内容无关紧要。 Y86程序集似乎不支持诸如
.quad ?
指令之类的东西,这些指令会使内存保留变得清晰。关于c - C至Y86组装,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/40319445/