我需要为处理器(或基于寄存器的虚拟机)编写一个 32 位模拟器。 为简单起见,RAM 是一个字节数组,当我需要加载字、半字或字节时,我会将其转换为 (int32_t*) (int16_t*) 和 (int8_t*)。
(我知道这迫使我根据变量的类型来对齐变量。)
现在我想在调用函数时将参数压入堆栈。并在需要时将它们加载到函数中。
来源看起来像这样:
int8_t x = 1;
int8_t y = 2;
foo(x, y);
汇编器应类似于:
PUSH R1
PUSH R2
CALL _FUNC_FOO
_FUNC_FOO:
; prologoue
PUSH LR
PUSH FP
MOV FP SP
; loading parameters
LOAD_B R1 FP #8
LOAD_B R2 FP #12
; code
; ...
; epilogue
MOVE SP FP
POP FP
POP LR
RETURN
我的问题是,这段代码适用于 32 位字,甚至在具有小端架构的机器上适用于 16 和 8 位字。
8/16 位值将像
01-00-00-00
和 02-00-00-00
一样被推送到 RAM 中。
LOAD 指令将加载该 32 位字的第一个字节,该字节恰好包含正确的值。
如果我将虚拟机移植到任何使用小端架构的机器,LOAD 指令将加载错误的字节。
00-00-00-01
~~~~~
我该如何解决这个问题?
我强烈希望有一个独立于处理器架构的解决方案。
非常感谢!
“此代码适用于具有小端架构的机器上的 32 位字”。
我怀疑更多的情况是它适用于本地字节序与模拟字节序匹配的机器。这就是你问题的根源。您使用的是本机 32 位负载,而不是模拟的 32 位负载。这意味着您没有模拟字节顺序,也没有模拟对齐限制。
请注意,对齐可能会以两种方式出错:您的模拟具有更严格的对齐(您无法模拟对齐异常),或者本机环境具有更严格的对齐(您的模拟在有效加载/存储时中断)。
解决方案很简单:您需要正确模拟加载和存储。如何做到这一点取决于您的编程语言。