C语言新手求教:按双字节分组打印.obj文件十六进制内容
Hey there! Let's work through your LC3 .obj file printing problem together—you're super close, just a couple of tweaks needed to fix those two issues.
First, let's break down what's going wrong:
- Double-byte grouping isn't working: Reading character by character makes it hard to pair bytes into 16-bit LC3 instructions. Instead, we need to read two bytes at a time as a single unit.
- Spurious
ffffffffprefixes: This happens becausecharis typically a signed type. When a byte has its highest bit set (0x80 to 0xFF), it gets sign-extended to a 32-bit integer when passed toprintf, hence the extraffffffff. We just need to use unsigned types to avoid this.
Here's a revised version of your code that fixes both problems, with comments explaining each change:
#include <stdio.h> #include <stdint.h> #include <stdlib.h> int main() { FILE *file = fopen("your_file.obj", "rb"); // Open in binary mode! Critical for non-text files if (!file) { perror("Failed to open file"); return EXIT_FAILURE; } uint16_t instruction; // Stores 16-bit LC3 instruction (2 bytes) // Read two bytes at a time until end of file while (fread(&instruction, sizeof(instruction), 1, file) == 1) { // Note: If your .obj file uses big-endian byte order (LC3's standard), // you might need to swap bytes if your system is little-endian. // Uncomment the line below if you see reversed bytes in output: // instruction = ((instruction >> 8) & 0x00FF) | ((instruction << 8) & 0xFF00); printf("%04X\n", instruction); // %04X ensures 4-digit hex, uppercase (use %04x for lowercase) } fclose(file); return EXIT_SUCCESS; }
Wait, why the note about byte order? LC3 instructions are stored as big-endian in .obj files (high byte first), but many modern systems are little-endian. If you notice your output has the two bytes reversed (e.g., expecting 1234 but getting 3412), uncomment that byte-swap line to fix it.
Let me explain the key fixes:
- Binary mode: Opening the file with
"rb"instead of"r"is essential for reading non-text files like .obj—this prevents the system from messing with newline characters or interpreting bytes as text. uint16_t: This is an unsigned 16-bit integer type, so it perfectly holds one LC3 instruction without sign extension issues.freadfor two bytes: We read exactlysizeof(uint16_t)(2 bytes) per iteration, which naturally groups the bytes into the 16-bit units you need.%04Xformat specifier: This tellsprintfto print the 16-bit value as a 4-digit hex number, padding with leading zeros if needed. Sinceuint16_tis unsigned, there's no sign extension to cause theffffffffprefix.
If you prefer to read bytes individually (maybe for more control), here's an alternative approach that also works:
#include <stdio.h> #include <stdint.h> #include <stdlib.h> int main() { FILE *file = fopen("your_file.obj", "rb"); if (!file) { perror("Failed to open file"); return EXIT_FAILURE; } unsigned char byte1, byte2; // Read two bytes at a time while (fread(&byte1, sizeof(byte1), 1, file) == 1 && fread(&byte2, sizeof(byte2), 1, file) == 1) { uint16_t instruction = (uint16_t)byte1 << 8 | byte2; // Combine into big-endian instruction printf("%04X\n", instruction); } fclose(file); return EXIT_SUCCESS; }
This version reads each byte as an unsigned char (so no sign extension) and manually combines them into a 16-bit instruction, which is great if you want explicit control over byte order.
Either of these should give you the clean, double-byte grouped hex output you're expecting, without those annoying ffffffff prefixes.
内容的提问来源于stack exchange,提问作者user6394303

