在我所在的班级中,我们被分配到一个简单的mips模拟器。我的程序应该处理的指令是在二进制文件中给出的。我不知道如何从该文件中获取任何可用的内容。这是我的代码:
import struct
import argparse
'''open a parser to get command line arguments '''
parser = argparse.ArgumentParser(description='Mips instruction simulator')
'''add two required arguments for the input file and the output file'''
parser.add_argument('-i', action="store", dest='infile_name', help="-i INPUT_FILE", required=True)
parser.add_argument('-o', action="store", dest='outfile_name', help="-o OUTPUT_FILE_NAME", required=True)
'''get the passed arguments'''
args = parser.parse_args()
class Disassembler:
'''Disassembler for mips code'''
instruction_buffer = None
instructions_read = 0
def __init__(self, filename):
bin_file = None
try:
bin_file = open(filename, 'rb')
except:
print("Input file: ", filename, " could not be opened. Check the name, permissions, or path")
quit()
while True:
read_bytes = bin_file.read(4)
if (read_bytes == b''):
break
int_var = struct.unpack('>I', read_bytes)
print(int_var)
bin_file.close()
disembler = Disassembler(args.infile_name)
所以,起初我只打印了我读过的4个字节,看看返回了什么。 我希望看到普通的比特(只有1&0; s和0' s)。我得到的是我读过的字节串。所以我试着谷歌搜索我能做些什么。所以我发现我可以使用struct将这些字节字符串转换为整数。以类似于(4294967295,)的格式输出它们。
这仍然很烦人,因为我必须修剪它以使其成为可用的整数,然后我仍然必须将其转换为位(基数2)。很高兴我可以将struct读取为有符号或无符号的字节,因为输入文件输入的一半是带符号的32位数字。
所有这些似乎比从二进制文件中获取位更复杂。有更简单的方法吗?你也可以解释一下,就像你对那些不太熟悉深奥的python代码并且对二进制数据不熟悉的人一样吗?
我的总体目标是从我读过的每4个字节中直接获得32位。该文件的开头是mips操作码列表。所以我需要能够看到这些数字的特定部分,比如前5位,然后是接下来的6位,依此类推。文件末尾包含32位有符号整数值。这两个文件由break操作码分隔。
感谢您提供给我的任何帮助。它让我发疯,我无法通过搜索找到任何直接的答案。如果你想看到二进制文件,告诉我在哪里发布它。
答案 0 :(得分:1)
请记住,普通的Python整数没有固定的位宽:它们的大小和它们需要的一样大。当您想要将有符号整数转换为位串时,这可能很烦人。我建议您坚持使用目前正在做的事情:使用
将4字节的块转换为无符号整数n = struct.unpack('>I', read_bytes)[0]
然后使用format(n, '032b')
或'{0:032b}'.format(n)
将其转换为位字符串,如果要打印位。
要访问或修改整数中的位,您不应该为字符串转换而烦恼,而应该使用Python的按位运算符&
,|
,{ {1}},^
,<<
,>>
。例如,~
为您提供(n >> 7) & 1
的第7位。
有关这些运算符的详细信息,请参阅Python文档中的Unary arithmetic and bitwise operations和以下部分。
答案 1 :(得分:0)
这样您就可以访问文件中的每个位。
"".join(format(i, "08b") for i in byte_string)
例如:
>>> "".join(format(i, "08b") for i in b"\x23\x54a")
'001000110101010001100001'