我正在基于现有的 RISC ISA 在 verilog 中设计一个 16 位 ALU。ISA 规定,当操作无符号时,进位标志被设置;当操作有符号时,溢出被设置。有趣的是 ISA 实现ADD和SUB指令可对有符号数和无符号数进行操作。由于签名与未签名只是一个解释问题,我最初的想法是执行如下操作。溢出与进位的想法只是解释问题,因此对两者使用相同的函数。
module ALU();
input wire [15:0]x;
input wire [15:0]y;
input wire [8:0]opcode;
output reg [15:0] result;
output reg CFlag; // Carry
output reg FFlag; // Overflow
if(opcode == ADD) begin
result = x + y;
// x and y have the same sign, result has a different sign.
CFlag = FFlag = (x[15] ~^ y[15]) & res[15] ^ x[15];
end
endmodule
Run Code Online (Sandbox Code Playgroud)
但是这种边缘情况(以 4 位显示)又如何呢?
x …Run Code Online (Sandbox Code Playgroud) 您知道有什么方法可以有效地检查 x86 左移算术上是否发生溢出/下溢吗?
我已经意识到并读到将 auint16_t与另一个uint16_t相乘会得到一个整数(它实际上似乎是一个有符号整数?请参阅:)。鉴于此,我是否必须假设以下函数f会产生未定义的行为,因为会出现有符号整数溢出?
会发生溢出,因为x*x对于x=45000“几乎”的结果INT32_MAX,如果再次乘以 就会溢出x。
(顺便说一句:在我的平台上int是一个int32_t)
#include <stdio.h>
#include <stdint.h>
uint16_t f(uint16_t x) {
printf("%zu\n", sizeof(x)); // <-- 2
printf("%zu\n", sizeof(x * x)); // <-- 4
return x * x * x;
}
int main()
{
uint16_t x = 45000;
uint16_t y = f(x);
}
Run Code Online (Sandbox Code Playgroud)
会发生溢出,因为x*x对于x=45000“几乎”的结果INT32_MAX,如果再次乘以 就会溢出x。
这是正确的,还是我做出了一些错误的假设?
我想知道 NEG 指令是否也会影响溢出标志。我知道它否定变量的值,但无法确定它是否影响溢出标志。
mov al, -1
add al, 130
Run Code Online (Sandbox Code Playgroud)
我正在尝试回答我的 x86 汇编课程教科书中的一个问题。其中一个示例要求解释为什么 over 标志会帮助您确定在这种情况下 al 的最终值是否在有效的有符号范围内。
我最初的想法是应该调用溢出标志,因为 -1 + 130 = 129,这超出了有符号 8 位整数的范围,而 al 是 EAX 寄存器的最低 8 位。但是当我在 Visual Studio 中运行此代码时,我没有看到设置了溢出标志。