在 MIPS 中从内存加载 bytes/halfwords
Load bytes/halfwords from memory in MIPS
我被要求使用 .byte 和 .word 指令创建一个数据段,以将值 0x01、0x02、0x03、0x04 存储为字节,将值 0x12345678 存储为字。我的代码是:
.data
b1: .byte 0x01
b2: .byte 0x02
b3: .byte 0x03
b4: .byte 0x04
w1: .word 0x12345678
然后我想使用lbu、lhu和lw分别加载值:0x01、0x0201和0x12345678到$t0、$t1、$t2。
我为此所做的是:
lbu $t0,b1 #this works
lhu $t1,0(b2) #this doesn't work, gets an error
lw $t2,w1 #also works
我的错误是inst/data 中的异常和未对齐的地址提取:0x10010001。
如何加载超过 1 个字节作为半字?我在数据段中的变量声明错误吗?我可能想要这样的东西吗:
byte_array: .byte 0x01,0x02
谢谢大家的帮助。
您正在尝试加载声明为 .byte
的半字 (lhu
)。这是大小不匹配,这会导致您收到错误。
但是处理器不关心大小不匹配,而是对齐。所以,如果你想加载一个半字(两个字节),它们必须从偶数字节边界开始,这不是你的数据设置的情况。
lhu $t0, b1
会起作用,lhu $t0,b3
和 lhu $t0,w1
也会起作用,因为这些数据位于偶数地址。但是,b2
和 b4
位于奇数地址。
C 编译器不会让您首先执行大小不匹配的加载,如果没有一些严重的转换,这会让您回到 MIPS 上的这些未对齐错误。此外,x86 处理器将允许未对齐的访问,但在某些情况下,它们会比对齐的等效项慢。
因为未对齐的访问需要更多的硬件,而且编译器通常可以使用他们的类型系统来避免这些问题,所以一些设计选择放弃额外的硬件,MIPS 就是其中之一。
您还可以通过插入填充来改变对齐方式——在 b1
和 b2
之间插入一个额外的字节会改变 b2
的对齐方式,从而允许加载 b2
和b3
使用 lhu
。因为 w1
被声明为 .word
汇编器知道它需要字对齐,所以在 b1
和 b3
之间插入一个字节将导致 w1
需要 3 个字节的附加对齐填充(由于使用了 .word
数据声明,汇编程序将提供)。
当你使用这种大小不匹配的时候,也会有字节顺序的问题。 MIPS 模拟器将使用与底层处理器相同的字节顺序,因此在加载 2 个字节时通常会看到小字节序行为。如果你声明两个 .bytes
而不是使用一个 .half
你将不得不选择一个字节顺序。
我被要求使用 .byte 和 .word 指令创建一个数据段,以将值 0x01、0x02、0x03、0x04 存储为字节,将值 0x12345678 存储为字。我的代码是:
.data
b1: .byte 0x01
b2: .byte 0x02
b3: .byte 0x03
b4: .byte 0x04
w1: .word 0x12345678
然后我想使用lbu、lhu和lw分别加载值:0x01、0x0201和0x12345678到$t0、$t1、$t2。
我为此所做的是:
lbu $t0,b1 #this works
lhu $t1,0(b2) #this doesn't work, gets an error
lw $t2,w1 #also works
我的错误是inst/data 中的异常和未对齐的地址提取:0x10010001。 如何加载超过 1 个字节作为半字?我在数据段中的变量声明错误吗?我可能想要这样的东西吗:
byte_array: .byte 0x01,0x02
谢谢大家的帮助。
您正在尝试加载声明为 .byte
的半字 (lhu
)。这是大小不匹配,这会导致您收到错误。
但是处理器不关心大小不匹配,而是对齐。所以,如果你想加载一个半字(两个字节),它们必须从偶数字节边界开始,这不是你的数据设置的情况。
lhu $t0, b1
会起作用,lhu $t0,b3
和 lhu $t0,w1
也会起作用,因为这些数据位于偶数地址。但是,b2
和 b4
位于奇数地址。
C 编译器不会让您首先执行大小不匹配的加载,如果没有一些严重的转换,这会让您回到 MIPS 上的这些未对齐错误。此外,x86 处理器将允许未对齐的访问,但在某些情况下,它们会比对齐的等效项慢。
因为未对齐的访问需要更多的硬件,而且编译器通常可以使用他们的类型系统来避免这些问题,所以一些设计选择放弃额外的硬件,MIPS 就是其中之一。
您还可以通过插入填充来改变对齐方式——在 b1
和 b2
之间插入一个额外的字节会改变 b2
的对齐方式,从而允许加载 b2
和b3
使用 lhu
。因为 w1
被声明为 .word
汇编器知道它需要字对齐,所以在 b1
和 b3
之间插入一个字节将导致 w1
需要 3 个字节的附加对齐填充(由于使用了 .word
数据声明,汇编程序将提供)。
当你使用这种大小不匹配的时候,也会有字节顺序的问题。 MIPS 模拟器将使用与底层处理器相同的字节顺序,因此在加载 2 个字节时通常会看到小字节序行为。如果你声明两个 .bytes
而不是使用一个 .half
你将不得不选择一个字节顺序。