Assembly 仅通过ADD、SUB、MUL和DIV指令实现位操作

Assembly 仅通过ADD、SUB、MUL和DIV指令实现位操作,assembly,bitwise-operators,Assembly,Bitwise Operators,我正在写一个编译器——只是为了好玩和提高我的技能。我想实现C语言的一个子集。问题是:我正在编译一个名为Sextium II的理论16位RISC处理器的汇编程序(我们过去在大学教汇编程序) 处理器只使用16个命令,并且没有一个是位操作。我想实现C位运算符——然后是半精度浮点运算——但我不知道如何仅使用ADD、SUB、MUL和DIV指令实现位运算。位移位非常容易,只需乘以或除以2^n,其中n是移位长度。但是和,或,不是或异或呢 编辑 需要说明的是:处理器仅使用16位有符号U2算术进行计算。如果您查看

我正在写一个编译器——只是为了好玩和提高我的技能。我想实现C语言的一个子集。问题是:我正在编译一个名为Sextium II的理论16位RISC处理器的汇编程序(我们过去在大学教汇编程序)

处理器只使用16个命令,并且没有一个是位操作。我想实现C位运算符——然后是半精度浮点运算——但我不知道如何仅使用
ADD
SUB
MUL
DIV
指令实现位运算。位移位非常容易,只需乘以或除以
2^n
,其中
n
是移位长度。但是
不是
异或

编辑
需要说明的是:处理器仅使用16位有符号U2算术进行计算。

如果您查看add的逐位真值表,例如:

a b  c r
0 0  0 0
0 1  0 1
1 0  0 1
1 1  1 0
a和b是输入操作数,r是结果,c是执行

从按位角度看,add是一个xor。但要将其用作一般的异或运算,需要执行16个加法运算,每一位加上屏蔽一个操作数和提取结果位的所有工作

a b  c r
0 1  0 1
1 1  1 0
再次关注加法,但如果b操作数始终为1,则会得到一个not函数。在这里,需要掩蔽和转移

当然你没有掩蔽和移动,是吗

乘数将向左移动,乘以2表示1乘以4的移动,即2的移动,依此类推。同样,分水岭也意味着右移。除以4表示2的移位,除以8表示3的移位,依此类推。您可以通过这种方式屏蔽单个位,除以8向右移动3,然后乘以0x8000向左移动15,然后除以0x1000。这是否与使用0x0008进行anding相同

如果这是可行的,那么你可以说乘以0x100,然后除以0x100,这和用0xFF00进行anding是一样的


它是有符号乘(除)还是无符号乘(除)?或者两者都有?

速度会很慢,但是x和1是x MOD 2,使用循环,每次都移位,可以构造16位和。1位x或y是(x和1)| |(y和1)(我假设您已经实现了这一点),同样,循环将为您提供16位版本。类似于XOR和NOT。我相信这可以用一种更聪明的方式来完成,但这可以作为一种退路。所有的运算都是在16位有符号的U2算法上进行的。当涉及到符号位时,这可能会改变乘和除的情况。例如,0x8000*0x7FFF的无符号乘法为0x3FFF8000,其中0x8000*0x7FFF的有符号乘法为0xC0008000。您可能没有一个16位*16位=32位的结果,因此这两个结果可能看起来相同(实际上我希望它们会这样做),但是将0x8000除以0x1000得到0x0008无符号和0xFFF8有符号。谢谢。我以为会有一些黑客让事情更快,但显然没有。我将接受你的回答。听起来教学计算机需要更多的说明,或者可能还有其他一些我们不知道的说明。例如一个nor或nand和一些使用立即数的方法,你可以做任何逻辑运算。不,只有16条指令,包括NOP。