def assemble(code):
    final = []
    for line in code:
        if isinstance(line, Label):
            final.append(line)
            continue
        mnemonic, operands = line[0], line[1:]
        operand_fmts = opcode_table[mnemonic]['operands']
        final_operands = []
        for i, operand in enumerate(operands):
            if isinstance(operand, Operand):
                final_operands.append(operand)
            elif isinstance(operand, Constant):
                final_operands.append(Operand(
                    OperandTypes.CONSTANT_INDEX,
                    operand.index
                ))
            elif isinstance(operand, dict):
                final_operands.append(operand)
            elif isinstance(operand, Label):
                final_operands.append(operand)
            else:
                final_operands.append(Operand(
                    operand_fmts[i][1],
                    operand
                ))
        final.append(Instruction.create(mnemonic, final_operands))
    label_pcs = {}
    current_pc = 0
    for ins in final:
        if isinstance(ins, Label):
            label_pcs[ins.name] = current_pc
            continue
        current_pc += ins.size_on_disk(current_pc)
    current_pc = 0
    for ins in final:
        if isinstance(ins, Label):
            continue
        for i, operand in enumerate(ins.operands):
            if isinstance(operand, dict):
                for k, v in operand.items():
                    if isinstance(v, Label):
                        operand[k] = Operand(40, label_pcs[v.name] - current_pc)
            elif isinstance(operand, Label):
                ins.operands[i] = Operand(
                    40,
                    label_pcs[operand.name] - current_pc
                )
        current_pc += ins.size_on_disk(current_pc)
        yield ins