1
1
你的问题涉及多个层面,所以我试着一个一个地解决它们。。。
机器的内存可按字节寻址。第一个字节有地址0,第二个字节有地址1,等等。。。每当我在这个答案中写关于内存内容的内容时,我都会使用以下格式:
如果你愿意加载
发件人地址
单词
发件人地址
在…上
机器
在…上
大端元
机器
( 256 is 2 8 ,这个幻数来自“一个字节是8位”,一位可以包含两个值(0或1),一个字节有8位,所以一个字节可以包含2 不同的值) 在这两种情况下,CPU将从内存中读取相同的四个字节(在地址0x800000到0x800003处),但端序定义了它们作为字值的最后32位出现的顺序。
这个
为其目标平台配置良好的汇编器将对程序员隐藏端点,以利用字值 实用的 所以当你定义内存值时,比如:
汇编程序将解析文本(您的源代码是text(!),i、 e.一个字符是一个字节值-在ASCII编码中,如果您在UTF8文本编辑器中写入源代码并使用非ASCII字符,则它们可能跨多个字节进行编码,ASCII可打印字符在ASCII和UTF8中具有相同的编码,并且仅占用单个字节)“0x11223344”(10个字节)
或:
然后使用
因此,程序员不必每次在源代码中某处写入32位值时都考虑endianness,汇编程序将解析并将其处理为字节值的目标变量。
如果程序员想要定义四个字节
当用声明字节值时
调试器最后是调试器的内存/寄存器视图。。。这个工具将再次努力工作 直观/方便 因此,当您检查内存视图并将其配置为字节时,内存将显示为:
当您将其切换到“word”视图时,它将使用配置的端序以目标平台顺序连接字节,即在MARS/SPIM中,作为小端序平台,它将显示在同一内存中:
(如果还包括ASCII视图,它是否也“文字化”了?如果是,那么它将看起来像
默认情况下,寄存器视图通常显示十六进制字值,即从该地址0x800000将字加载到
如果您感兴趣的是用于该加载的内存中第一个字节的值是多少,此时您必须应用您对该目标平台的端序的知识,并查看寄存器视图中的前两个数字“34”(大端序),或最后两个数字“31”(小端序)(或者更确切地说,在字节视图模式下使用内存视图以避免任何错误)。 因此,有了以上所有信息,运行时检测代码应该很容易理解(遗憾的是,我目前没有MARS/SPIM,所以我没有验证它是否有效,请告诉我):
它有什么好处?只要您为单目标平台编写软件,并且由目标CPU存储/加载文字,您就不需要关心Endiance。 但如果你有多平台的软件,它确实可以保存二进制文件。。。为了使文件在两个大/小端点平台上以相同的方式工作,文件结构的规范还必须指定文件数据的端点。然后根据该规范,一种类型的目标平台可能会将其读取为“本机”字值,另一种平台将不得不洗牌字值中的字节以读取正确的字值(此外,规范还应指定“字”的字节数:)。如果您将洗牌器包括到保存/加载例程中,使用端点检测例程来决定是否必须洗牌字字节,那么这样的运行时测试可能很方便。这将使目标平台的endianness对其余代码“透明”,剩下的代码只需将其本机“word”值发送到保存/加载例程,您的保存/加载可能在每个平台上使用相同的源代码(至少只要您使用一些多平台的可移植编程语言,如C,当然MIPS的程序集根本无法在不同的CPU上工作,需要从头重写)。 此外,网络通信通常使用自定义二进制协议(通常包装在网络层最常见的TCP/IP数据包中,甚至是加密的,但您的应用程序将在某一点从中提取原始字节内容),然后发送/接收数据的端序性问题,“其他”平台必须洗牌字节以读取正确的值。 其他平台(非MIPS)
可以应用上面的几乎所有内容,只需检查
|
Ilya Loskutov · 无法将单词加载到寄存器中 2 年前 |
Ari157 · x86_64 Linux程序集中的逻辑与实现 2 年前 |
Arya · 汇编语言中的“标签”——操作码 2 年前 |
S1mple · 通过gcc生成64位共享库时的“未定义的主引用” 2 年前 |
R0M2 · 为什么“GCC”忽略汇编代码的-fno pic 2 年前 |
Akagi Akira · 如何在gnu汇编程序中组装MIPS cpu 2 年前 |