我在C代码中遇到了一个小问题
本质上,我正在阅读一个二进制文件,并提取了指令,每条指令的长度为4字节,每条指令的大小为32位。
我有一个程序计数器,它从0
开始,在地址1024
结束,每次读取4个字节
所以
- 指令0 =程序计数器@0,
- 指令1 =程序计数器@4
现在这不是问题了,我的代码正确地阅读了文件的内容
问题是:
我希望存储返回一个指针到最后7位的指令
所以如果我有指令@程序计数器0 =01111111111100000000000100010011
以下哪种等效十六进制表示形式为:
unsigned char instruction[INSTRUCTION_SIZE] = { 0x7F, 0xF0, 0x01, 0x13 };
其中INSTRUCTION SIZE
是4
,因为每个指令是4字节,因此32位长。
我希望返回一个包含最后7位的变量,在我们的例子中是0010011
现在,我有一个简单的函数,可以打印最后7位
void print_first_instruction(unsigned char *instruction) {
unsigned char value = instruction[0];
unsigned char last_seven_bits = value & instruction[0];
char bit0 = 0x00;
printf("\nLast 7 bits in binary: ");
for (int i = 6; i >= 0; i--) {
bit0 |= (last_seven_bits >> i) & 0x01; // shift the bits and use bitwise OR to assign the bits to bit0
bit0 <<= 1; // shift bit0 to the left to make space for the next bit
printf("%d", (last_seven_bits >> i) & 0x01);
if (bit0 == 0x13) {
printf("Add command");
}
}
}
int main(int argc, char *argv[]) {
FILE *file;
char *filename = "print.mi";
int i, j;
long filesize;
file = fopen(filename, "rb");
if (file == NULL) {
printf("Error: could not open file.\n");
return 1;
}
fseek(file, 0L, SEEK_END);
filesize = ftell(file);
rewind(file);
// read the file and store its contents in instruction_memory
for (i = 0; i < filesize; i += INSTRUCTION_SIZE) {
fread(&blob.instruction_memory[i], 1, INSTRUCTION_SIZE, file);
}
for (program_counter = 0; program_counter < INSTR_MEM_SIZE; program_counter += INSTRUCTION_SIZE) {
unsigned char instruction[INSTRUCTION_SIZE];
for (int j = INSTRUCTION_SIZE - 1; j >= 0; j--) {
instruction[j] = blob.instruction_memory[program_counter + j];
}
print_first_instruction(instruction);
}
fclose(file);
return 0;
}
此代码打印第一条指令的最后7位
第一条指令是01111111111100000000000100010011
因此,它提取0010011
现在,我希望编写一些代码来检查最后一位是否等于0010011
在这种情况下,它显然是,所以我想打印到标准输出(“添加操作”)已被发现
我该怎么做。
因此,我还想存储最后7位,以防我希望函数使用除第一个指令以外的其他指令
4条答案
按热度按时间kiayqfof1#
32位指令似乎是以大端格式存储在内存中的,即:最高有效字节在前,最低有效字节在后。对于这种字节排序,要提取最低有效的7位,您可以只屏蔽第4个字节的低7位:
请注意,当今大多数台式机和笔记本电脑中的字节顺序都是小端,因此为了将文件内容转换为32位指令,需要特定的代码:
幸运的是,上面的代码在大多数平台上只编译为1或2条指令。
1tu0hz3e2#
你不需要一位一位地移位。下面你有一个函数的例子,它根据endianess(字节顺序)转换为uint32_t并从中提取n位。
https://godbolt.org/z/n4xhhrKfG
xxe27gdn3#
0x26
(加倍)而不是0x13
。0x13
的比较应发生在 * 循环后 * 以提取位,而不是在每次迭代中。qoefvg9y4#
要从包含4个元素的字符数组(或子数组)的最后一个元素中提取最后7位,您应该使用掩码
0x7F
。因此,一个返回4个元素的字符数组的最后一个元素的7位的函数可以如下所示
如果需要,可以将返回类型从
unsigned char
更改为int
。在函数的调用者中,你可以写例如