我目前正在开发一个gameboy模拟器并测试我的模拟器的正确性,我正在使用GBDK为我的模拟器编译c程序。
我注意到编译器(如预期的那样)通过旋转来优化乘法与常量的乘法,这些常量是 2 的幂。但是,对于给定的功率,它似乎不会产生正确的旋转量。
例如以下非常简单的程序:
#include <gb/gb.h>
unsigned char one() { return 1; }
void main()
{
unsigned char r;
// Force compiler to generate muliplication by deferring the '1'
r = one() * 32;
// Store result somewhere
*((unsigned char*)(0xFFFE)) = r;
}
生成以下程序集:
___main_start:
_main:
push bc
; reproduce.c 14
; genCall
call _one
ld c,e
; genLeftShift
ld a,c
rr a
rr a
rr a
and a,#0xE0
ld c,a
; reproduce.c 16
; genAssign
ld de,#0xFFFE
; genAssign (pointer)
ld a,c
ld (de),a
; genLabel
00101$:
; genEndFunction
pop bc
ret
___main_end:
.area _CODE
对我来说这似乎是不正确的,因为 RR 指令实际上是通过进位标志旋转的,有效地使其成为 9 位旋转。这意味着应该有一个额外的旋转来产生正确的结果,而不是当前 (0x40) 的错误结果。
可视化:
Start: A = 00000001 Carry = 0
RR A: A = 00000000 Carry = 1
RR A: A = 10000000 Carry = 0
RR A: A = 01000000 Carry = 0 <- WRONG!
谁能验证这确实是GBDK附带的SDCC编译器中的一个错误?我也对旋转后使用 and 指令感兴趣。
使用来自 sourceforge 的最新 (3-2.93) 版本的 GBDK for windows。