将十六进制字符串的最后5位数转换为C中的2位补码

时间:2014-10-19 23:54:31

标签: c lc3

继续我之前的问题Having trouble reading strings from a file in C and manipluating them as an lc3 disassmbler

我现在需要在使用ADD& amp;的lc3反汇编程序中实现立即寻址模式。和

例如,如果文件包含:

1283

5105

1df7

506F

我想打印出来:

添加r1,r2,r3

和r0,r4,r5

添加r6,r7,-9

和r0,r1,15

我怎么能打印出-9和15我知道我需要将它转换为二进制补码但不确定如何。

这是我的If语句引用ADD指令的代码,即。输出的第3行和第1行

while (fscanf(file, "%s", hexString) != EOF){

    long int instruction = strtol(hexString, NULL, 16);

        if (instruction >> 12 == 0b0001){ //op code is ADD

            if ((instruction >> 5) & 0b001){ //is using “immediate” addressing mode

            dr = (instruction >> 9) & 0b111;
            sr1 = (instruction >> 6) & 0b111;
            sr2 = (!instruction) & 0b11111 + 1; // this needs to convert to twos complement

            printf("and r%d,r%d,%d \n", dr, sr1,sr2);   

            } else {

            dr = (instruction >> 9) & 0b111; // turns other bits to zero
            sr1 = (instruction >> 6) & 0b111;
            sr2 = (instruction) & 0b111;

            printf("add r%d,r%d,r%d \n", dr, sr1, sr2);
            }
        } else if ....

下载lc3指令集的副本以供参考http://ece224web.groups.et.byu.net/reference/LC3_Instructions.gif

1 个答案:

答案 0 :(得分:4)

问题是使用逻辑NOT代替按位NOT。

请改为尝试:

sr2 = (0x10 & instruction) ? ((~(instruction & 0x1F)) + 1) : (instruction & 0x1F);

我正在利用二进制补码的属性:如果设置了最高有效位,则数字为负数,我们可以通过翻转所有位(〜,按位NOT)并加1来使其为正数

看起来你试图这样做,但你需要意识到这一点! (逻辑NOT)可能会返回1(如果val == 0)或0(如果val!= 0)。

说明差异的例子:

uint8_t value = 0xAA;
uint8_t logical_not = !value;
uint8_t bitwise_not = ~value;

printf("initial value: 0x%02X, logical not: 0x%02X, bitwise not: 0x%02X\n", value, logical_not, bitwise_not);

您期望看到的是:

initial value: 0xAA, logical not: 0x00, bitwise not: 0x55

添加您需要的所有内容以便自行验证:

测试程序:

#include <stdio.h>

void main(void)
{
    uint8_t value = 0xAA;   // Test value: 0b10101010
    uint8_t lnot = !value;  // logical not of test value
    uint8_t bnot = ~value;  // bitwise not of test value

    printf("v: 0x%02X, L: 0x%02X, B: 0x%02X\n", value, lnot, bnot);
}

节目输出:

$ gcc test.c
$ ./a.exe
v: 0xAA, L: 0x00, B: 0x55
$