作为赋值的一部分,我在python中编写汇编程序,它使用简化的汇编语言并输出二进制机器语言。我的部分代码如下所示,我在两遍中从汇编代码中读取。从文件asm_file读取的第一个块中的第一行(open(filename,“r”)的第一行作为asm_file)似乎没有执行。第二个是执行正常,它没有输出正确的二进制文件,因为第一个块似乎没有正确运行或根本没有。我使用“with open(filename。”r“)作为文件:”正确吗?我错过了什么?提前谢谢。
为了完整性,在代码下面给出了一个输入文件:
if __name__ == "__main__":
#fill Symbol Table and C instruction Tables
symbol_table = symbolTable()
symbol_table.initialiseTable()
comp_table = compTable()
comp_table.fillTable()
dest_table = destTable()
dest_table.fillTable()
jump_table = jumpTable()
jump_table.fillTable()
#import the file given in the command line
filename = sys.argv[-1]
#open output_file
output_file = open('output.hack', 'w')
#open said file and work on contents line by line
with open(filename, "r") as asm_file: ##### This one doesn't seem to run because
#1st pass of input file ##### The print command below doesn't output anything
num_instructions = -1
for line in asm_file:
#ignoring whitespace and comments
if line != '\n' and not line.startswith('//'):
num_instructions += 1
#remove in-line comments
if '//' in line:
marker, line = '//', line
line = line[:line.index(marker)].strip()
#search for beginning of pseudocommand
if line.startswith('('):
num_instructions -= 1
label = line.strip('()')
address = num_instructions + 1
symbol_table.addLabelAddresses(label, address)
print(num_instructions) ###### This print command doesn't output anything
with open(filename, "r") as asm_file:
#2nd pass of input file
for line in asm_file:
#ignoring whitespace and comments
if line != '\n' and not line.startswith('//') and not line.startswith('('):
#remove in-line comments
if '//' in line:
marker, line = '//', line
line = line[:line.index(marker)].strip()
#send each line to parse function to unpack into its underlying fields
instruction = parseLine(line.strip(' \n'))
inst = Instruction(instruction)
binary_string = inst.convertToBin()
#write to output file
output_file.write(binary_string +'\n')
output_file.close()
输入文件示例:
// This file is part of www.nand2tetris.org
// and the book "The Elements of Computing Systems"
// by Nisan and Schocken, MIT Press.
// File name: projects/06/max/Max.asm
// Computes R2 = max(R0, R1) (R0,R1,R2 refer to RAM[0],RAM[1],RAM[2])
@R0
D=M // D = first number
@R1
D=D-M // D = first number - second number
@OUTPUT_FIRST
D;JGT // if D>0 (first is greater) goto output_first
@R1
D=M // D = second number
@OUTPUT_D
0;JMP // goto output_d
(OUTPUT_FIRST)
@R0
D=M // D = first number
(OUTPUT_D)
@R2
M=D // M[2] = D (greatest number)
(INFINITE_LOOP)
@INFINITE_LOOP
0;JMP // infinite loop
答案 0 :(得分:1)
您的问题似乎是您的代码检查一行是否以(
开头,但在程序集中它在指令之前有一个选项卡,因此它不起作用。您应该在第一个if语句之后执行line.strip()
,如此
with open(filename, "r") as asm_file:
num_of_instructions = -1
for line in asm_file
if line != "\n":
line.strip()
#rest of code
顺便说一下,每次找到一行时都应该执行print语句吗?因为如果没有,你应该把它放在for循环之后。这就是为什么它没有输出任何东西
编辑:正如@TimPeters所说,如果print语句以一个开括号开头并且其中有注释,那么print语句也只会执行
答案 1 :(得分:0)
在第一个with
中,从
#search for beginning of pseudocommand
你确定你不希望这样,以下几行会缩小一个级别吗?
按原样,到达print
的唯一方法是,如果一行符合两者
if '//' in line:
和
if line.startswith('('):
输入文件中没有任何行满足两者,因此print
永远不会执行。
在第二个with
中, 之后只有两个缩进行
if '//' in line: