Assembly 二进制右移,仅给出加法
我在一个项目中工作,我正在读取内存位置,需要以ASCII格式输出它们的十六进制值 这种语言给了我一个16位的字长,所以我需要一次除法来获取一个半字节来转换为十六进制。不幸的是,该语言仅为数学/逻辑函数提供and、or、not和add 我想我可以通过左移和测试负标志来创建所需的效果,在移动后在末尾添加1,但我想必须有更好的方法来实现这一点 任何洞察都将不胜感激。使用,您可以将除最后一个有效半字节外的所有位设置为零:Assembly 二进制右移,仅给出加法,assembly,binary,logic,lc3,Assembly,Binary,Logic,Lc3,我在一个项目中工作,我正在读取内存位置,需要以ASCII格式输出它们的十六进制值 这种语言给了我一个16位的字长,所以我需要一次除法来获取一个半字节来转换为十六进制。不幸的是,该语言仅为数学/逻辑函数提供and、or、not和add 我想我可以通过左移和测试负标志来创建所需的效果,在移动后在末尾添加1,但我想必须有更好的方法来实现这一点 任何洞察都将不胜感激。使用,您可以将除最后一个有效半字节外的所有位设置为零: 0101010111010101 0000000000001111 AND ---
0101010111010101
0000000000001111 AND
----------------
0000000000000101
通过将整个内容向右移动,您可以读取下一个字节:
0101010111010101 SHR 4
----------------
010101011101
0000000000001111 AND
----------------
0000000000001101
这对你有用吗?你有带进位的附加功能吗?不是测试负数,而是在末尾加一个位,再加一个带进位的零,把它放回右边。其实省不了多少钱。到目前为止,我想不出另一种解决方案,向左移动,测试一点,如果设置为“向某个对象添加1”并移动该对象:
uint a,b,i;
b=0;
for(i=0;i<4;i++)
{
b=b+b;
if(a&0x8000) b+=1;
a=a+a;
}
如果上面的uint是16位,那么上面的uint将给你12位的右移。正如所写,a将在创建b的过程中被销毁。您可以反向尝试:您可以使用蛮力,而不是尝试执行正确的转换。以下是最高半字节的示例:
unsigned rez, tmp;
for (rez = 0, tmp = some_word & 0x0FFF; tmp != some_word; rez++, tmp += 0x1000);
所以我使用的原始方法有效。我还提出了另一个问题,以防有人再次遇到这个问题 我构建了一个子例程,一次计算4位,并根据计算结果创建一个数字,对于某些C风格的伪代码,它如下所示:
16bitSignedInt bin; //binary being analyzed
int value; //number being built
for (int i = 0; i < 4; i++) // while 0-3, for each nibble of the 16 bits
{
if (bin.bit15 = 1)
value += 8; // dominate bit in nibble
bin <<= 1; // left shift 1
if (bin.bit15 = 1)
value += 4; // 2nd bit in nibble
bin <<= 1; // left shift 1
if (bin.bit15 = 1)
value += 2; // 3rd bit in nibble
bin <<= 1; // left shift 1
if (bin.bit15 = 1)
value += 1; // last bit in nibble
bin <<= 1; // left shift 1
//do work with value
}
粗糙,但有效。已经应用掩蔽来清除不重要的部分。我遇到的问题是语言中没有右移操作。必须弄清楚如何通过对16位值进行有符号整数加法来创建该操作。我现在正在做的是屏蔽这个值,检查第15位是否有1,如果有,左移并加1,否则左移。这似乎真的很低效,我必须为这个方法中的每个半字节构建一个子程序。没有带进位的加法=/