ics-nju-wl / icspa-public

ICSPA for MOOC
51 stars 21 forks source link

A Bug: src/cpu/test/alu_test.c:109 'assert(cpu.eflags.SF == test_eflags.SF)' failed. #3

Open 521zhangxx opened 2 years ago

521zhangxx commented 2 years ago

这里是报错内容: 9CF3U2V_EWF_0VUXRE9LTM6

在alu.c文件中相关代码为: void set_SF(uint32_t result, size_t data_size){ result = sign_ext(result & (0xFFFFFFFF >> (32 - data_size)), datasize); cpu.eflags.SF = sign(result) }

在alu_test.c种相关代码为:①断言处代码,②是定义SF标志位代码 `3)(778ED7~0LW{7NQS1{HX

WIA N`Q99FW14J90PYP`C2J 但是我发现这两处代码均无错误,而alu.c 中的 sign() 函数在 include/cpu/alu.h中,源代码如下: THZ %C3ELDZR_J%2{XC~%{V 在这里可以看到,代码中的最终结果应该是32位的数据,然而标志位SF只是一位数据,所以需要将之转化为一位数据。 因此需要将之改变为:

define sign(x) (((uint_32_t)(x) >> 31) == 1)

这样返回值为布尔类型、一位数据。但是如果只改变这一处会报redefine错误,因此,同时还需要将src/cpu/cpu.c 中定义的sign(x)作出同样的修改。

ics-nju-wl commented 2 years ago

你的截图里面是ZF判断发现了错误

ics-nju-wl commented 2 years ago

sign函数的作用是取符号位,现在的框架代码写法应该没有问题的

521zhangxx commented 2 years ago

额,截错图了😭

r1ckhu commented 2 years ago

你的报错内容显示的是ZF标志位错误,而给出的相关代码是关于SF标志位的。 在给位域赋值的时候,只要不超过位域能表示的最大范围就应该不会有问题。同时,即使你把sign(x)修改成了(((uint32_t)(x) >> 31) == 1),使用sizeof(sign(0))测试发现,返回值仍然是32位的数据。

521zhangxx commented 2 years ago

图片截错了,这回改过来了

521zhangxx commented 2 years ago

你的报错内容显示的是ZF标志位错误,而给出的相关代码是关于SF标志位的。 在给位域赋值的时候,只要不超过位域能表示的最大范围就应该不会有问题。同时,即使你把sign(x)修改成了(((uint32_t)(x) >> 31) == 1),使用sizeof(sign(0))测试发现,返回值仍然是32位的数据。

不应该呀,表达式的返回值不是布尔类型嘛?但是经过这么修改,确实没有再报断言错误了

r1ckhu commented 2 years ago

你的报错内容显示的是ZF标志位错误,而给出的相关代码是关于SF标志位的。 在给位域赋值的时候,只要不超过位域能表示的最大范围就应该不会有问题。同时,即使你把sign(x)修改成了(((uint32_t)(x) >> 31) == 1),使用sizeof(sign(0))测试发现,返回值仍然是32位的数据。

不应该呀,表达式的返回值不是布尔类型嘛?但是经过这么修改,确实没有再报断言错误了

c语言默认没有bool类型吧,记得不是很清楚了?假如把代码改成((_Bool)(((uint32_t)(x) >> 31) == 1)),这样sizeof(sign(0))就是1了。 假如你怀疑是sign(x)出了问题,也许可以在设置SF之前,加入一行assert(sign(x) == my_sign(x)),将两个版本的sign(x)比较一下。

521zhangxx commented 2 years ago

嗯,收到

------------------ 原始邮件 ------------------ 发件人: @.>; 发送时间: 2022年10月25日(星期二) 中午11:25 收件人: @.>; 抄送: @.>; @.>; 主题: Re: [ics-nju-wl/icspa-public] A Bug: src/cpu/test/alu_test.c:109 'assert(cpu.eflags.SF == test_eflags.SF)' failed. (Issue #3)

你的报错内容显示的是ZF标志位错误,而给出的相关代码是关于SF标志位的。 在给位域赋值的时候,只要不超过位域能表示的最大范围就应该不会有问题。同时,即使你把sign(x)修改成了(((uint32_t)(x) >> 31) == 1),使用sizeof(sign(0))测试发现,返回值仍然是32位的数据。

不应该呀,表达式的返回值不是布尔类型嘛?但是经过这么修改,确实没有再报断言错误了

c语言默认没有bool类型吧,记得不是很清楚了?假如把代码改成((_Bool)(((uint32_t)(x) >> 31) == 1)),这样sizeof(sign(0))就是1了。 假如你怀疑是sign(x)出了问题,也许可以在设置SF之前,加入一行assert(sign(x) == my_sign(x)),将两个版本的sign(x)比较一下。

— Reply to this email directly, view it on GitHub, or unsubscribe. You are receiving this because you authored the thread.Message ID: @.***>