5.5 Printing an Assembler Program

Use the following function to get a string representation of an assembler instruction.

Function: int qsmm_instr_str (char *bufp, size_t bufsz, qsmm_instr_t instr, struct qsmm_dump_instr_desc_s *desc_p)

This function stores in a buffer bufp with size bufsz bytes a string representation of an instruction instr. If desc_p is not NULL, the function generates the string representation according to input parameters in *desc_p. If desc_p is NULL, the function generates the string representation according to default parameters. The function returns output parameters in either *desc_p or default parameters.

On success, the function returns a non-negative number of bytes required to store the string representation not counting finalizing byte 0 or returns INT_MAX if that number is greater than or equal to INT_MAX. The required number of bytes is also available in the field out_sz of qsmm_dump_instr_desc_s structure.

The required number of bytes greater than or equal to bufsz indicates the truncation of a string representation. In this case, if bufsz is positive, the function stores in bufp a truncated string representation with length bufsz–1 bytes and terminates the representation with byte 0. The function supports passing 0 for both bufp and bufsz to determine the length of a string representation.

On failure, the function returns a negative error code. Currently, the function can return the following error codes.

QSMM_ERR_INVAL

The argument bufsz is positive, but bufp is NULL.

QSMM_ERR_ILSEQ

Unable to convert a multibyte string to a wide string or vice versa according to a current locale.

QSMM_ERR_NOMEM

There was not enough memory to perform the operation.

The QSMM library contains an instance of qsmm_dump_instr_desc_s structure holding default parameters of generating string representations of assembler instructions. Use the following function to get a pointer to the instance.

Function: struct qsmm_dump_instr_desc_s * qsmm_get_default_dump_instr_desc ()

This function returns a pointer to default parameters of generating string representations of assembler instructions. You can change the parameters via the pointer. The function never returns NULL.

The description of a structure specifying the parameters of generating string representations of instructions is below.

Structure: qsmm_dump_instr_desc_s

This structure specifies the parameters of generating a string representation of an assembler instruction. The structure contains the following fields.

Field: char is_line_after_comment_above

If this field is not 0, the field do_print_comment_above is not 0, and the instruction has a comment above itself, insert an empty line after the comment and before the instruction. The function qsmm_prg_dump uses this field in a similar way to determine whether to insert an empty line after a comment above a procedure. The default is to insert an empty line.

Field: char is_line_after_multiline_comment_right

If this field is not 0, and the field do_print_comment_right is not 0, insert an empty line after an instruction with a comment to the right ending below the first line of instruction text if the next instruction has an adjacent comment to the right. The default is to insert an empty line.

Field: char is_space_after_comma

If not 0, insert a space after every comma outside string literals in instruction parameters. The default is to insert a space.

Field: char do_print_label

If not 0 and the instruction has a location label assigned, print the location label to the left of the instruction. If the instruction has multiple location labels assigned, print all labels except for the last one on separate lines. If there is no room between the last label and an instruction name, print the last label on a separate line too. The default is to print location labels.

Field: char do_print_name

If not 0, print an instruction name. The default is to print.

Field: char do_print_param

If not 0, print instruction parameters. The default is to print.

Field: char do_print_comment_above

If not 0 and the instruction has a comment above itself, print the comment. The default is to print.

Field: char do_print_comment_right

If not 0 and the instruction has a comment to the right, print the comment. If is 1, start printing the comment on a line with an instruction name. If is greater than 1, start printing the comment at a column specified by the field col_comment starting on the first line of instruction text satisfying the condition: a comment on that line and all subsequent lines of instruction text would not interfere with an instruction name and instruction parameters. If there are no lines satisfying that condition, print the comment at column col_comment just beneath the instruction text. The default is to print the comment at column col_comment without interfering with an instruction name and instruction parameters.

Field: char do_print_var

If not 0, a jprob or case instruction uses the name of a variable for a probability, and the field prob_type is equal to QSMM_PROB_PROFILE, print that name instead of a numeric probability in the instruction. Otherwise, print a numeric probability. The default is to print a variable name instead of a numeric probability where possible.

Field: char do_print_state_name

If this field is not 0, the field do_print_param is not 0, and an stt instruction has an associated state name, print the state name in the stt instruction. The default is to print a state name.

Field: char do_print_prob[QSMM_PROB_COUNT]

An array specifying additional types of probabilities to print in a comment for a jprob or case instruction to the right. Array indices are the elements of qsmm_prob_e enumeration (except for its last element) described in Emitting an Output Signal. If the field do_print_comment_right is not 0, an element of the array is not 0, and the index of the element is not equal to the field prob_type, qsmm_instr_str prints a probability of a corresponding type in the comment. When printing an instruction of a program disassembled using an assembler program template, if the instruction has ambiguous context in the template, qsmm_instr_str prints ‘?’ for probabilities in the comment. The default is not to print probabilities in the comment.

Field: int prob_prec

The number of digits after the decimal point to print for a probability in a prob instruction, for a probability in a jprob or case instruction according to the field prob_type, and for probabilities in a comment to the right of a jprob or case instruction according to the field do_print_prob. If this field is non-negative, use fixed-point notation. If this field is negative, use exponential notation with the number of digits after the decimal point equal to the absolute value of this field. The default number of digits to print after the decimal point is 2.

Field: long col_name

If this field is positive, it specifies a column to align an instruction name and a comment above the instruction. This field also specifies a column for the function qsmm_prg_dump to align directive names, comments above procedures, tail comments in procedures, and a tail comment in an assembler program. If this field is not positive, do not align an instruction name, directive names, and the comments. The default alignment column is 9.

Field: long col_param

If this field is positive, it specifies a column to align instruction parameters on their first line and, if instruction parameters occupy multiple lines, a column to indent them on the following lines. If this field is not positive, do not align or indent the instruction parameters. The default alignment column is 17.

Field: long col_comment

If this field is positive, it specifies a column to align a comment to the right of an instruction. If the field do_print_comment_right is greater than 1, the comment starts exactly at the column and does not interfere with an instruction name or instruction parameters. If this field is not positive, do not align the comment. The default alignment column is 33.

Field: long margin_right

If this field is positive, it specifies a right margin column for comments. The functions qsmm_instr_str and qsmm_prg_dump split longer comments into multiple lines. If this field is not positive, do not split comments into multiple lines based on a right margin column. The default is not to split.

Field: long margin_right_param

If this field is positive, it specifies a right margin column for the parameters of a user instruction. The function qsmm_instr_str splits longer parameters into multiple lines and uses positions of commas outside string literals as allowed split positions. If this field is not positive, do not split the parameters into multiple lines based on a right margin column. The default right margin column is 30.

Field: long line_comment_right_start

Output parameter. [New in QSMM 1.19] The function qsmm_instr_str stores here a zero-based index of a line of instruction text containing the first line of a comment printed to the right of the instruction. If the index is equal to the field nline_param, qsmm_instr_str has printed the comment just beneath the instruction. If this field is negative, qsmm_instr_str has not printed the comment. The function qsmm_prg_dump reads this field to insert an empty line after an instruction with a comment to the right ending below the first line of instruction text if the next instruction has an adjacent comment to the right.

Field: long nline_comment_right

Output parameter. The function qsmm_instr_str stores here the number of lines in a comment to the right of an instruction. If an instruction name or instruction parameters are too long, qsmm_instr_str may put the comment below the first line of instruction text. If qsmm_instr_str has not printed the comment, it sets this field to 0. The function qsmm_prg_dump reads this field to insert an empty line after an instruction with a comment to the right ending below the first line of instruction text if the next instruction has an adjacent comment to the right.

Field: long nline_param

Output parameter. The function qsmm_instr_str stores here the number of printed lines containing an instruction name and instruction parameters. The function qsmm_prg_dump reads this field to determine whether to insert empty lines around multi-line instructions and whether a comment to the right of an instruction ends on the last line of instruction text or beneath the instruction text and, therefore, can be adjacent to a comment of the next instruction.

Field: size_t out_sz

Output parameter. [New in QSMM 1.17] The number of bytes not counting finalizing byte 0 occupied by a string representation that would be printed by the function qsmm_instr_str. That number does not depend on buffer size passed to qsmm_instr_str.

Field: enum qsmm_prob_e prob_type

The type of a probability to print in a jprob or case instruction. See Emitting an Output Signal, for the description of elements of qsmm_prob_e enumeration. When printing an instruction of a program disassembled using an assembler program template, if the instruction has ambiguous context in the template, the function qsmm_instr_str prints ‘?’ for a probability. The default probability type is QSMM_PROB_AGGR.

Note: when converting a disassembled program or its specific instructions to a string representation, be sure to set the fields do_print_prob and prob_type of qsmm_dump_instr_desc_s structure to values consistent with the fields do_calc_prob and prob_type of qsmm_disasm_desc_s structure passed when creating the disassembled program. Otherwise, the function qsmm_instr_str or qsmm_prg_dump may print zero probabilities.

Use the following function to dump a program to a stream.

Function: int qsmm_prg_dump (qsmm_prg_t prg, struct qsmm_dump_prg_desc_s *desc_p, FILE *filep)

This function dumps a program prg to a stream filep. If desc_p is not NULL, the function dumps the program according to parameters in *desc_p. If desc_p is NULL, the function dumps the program according to default parameters.

In the current implementation the function does not modify *desc_p or default parameters (but can modify a structure instance addressed by the field dump_instr_desc_p of qsmm_dump_prg_desc_s structure). However, in a future implementation the function may modify them, for example, to store there statistics on the dumping process.

This function calls the function qsmm_instr_str to obtain string representations of individual assembler instructions and passes to the latter function the field dump_instr_desc_p of qsmm_dump_prg_desc_s structure referencing input and output parameters of generating the string representations.

The function returns a non-negative value on success or a negative error code on failure. Currently, the function can return the following error codes.

QSMM_ERR_ILSEQ

Unable to convert a multibyte string to a wide string or vice versa according to a current locale.

QSMM_ERR_NOMEM

There was not enough memory to perform the operation.

The QSMM library contains an instance of qsmm_dump_prg_desc_s structure holding default parameters of dumping a program. Use the following function to get a pointer to the instance.

Function: struct qsmm_dump_prg_desc_s * qsmm_get_default_dump_prg_desc ()

This function returns a pointer to default parameters of dumping an assembler program. You can change the parameters via the pointer. The function never returns NULL.

The description of a structure specifying the parameters of dumping a program is below.

Structure: qsmm_dump_prg_desc_s

This structure specifies the parameters of dumping an assembler program. The structure contains the following fields.

Field: char is_line_before_label

If not 0, insert an empty line before a line with a location label definition. If an instruction has multiple location labels assigned (dumped on separate lines), the function qsmm_prg_dump inserts an empty line only before the first location label definition. The default is to insert.

Field: char is_line_before_isolated_comment

If not 0, insert an empty line before a comment above an instruction. If not 0 and the field do_print_comment_head is not 0, insert an empty line before a comment above a procedure. If not 0 and the field do_print_comment_tail is not 0, insert an empty line before a comment at procedure end and before a comment at program end. The default is to insert.

Field: char are_lines_around_choice

If not 0, insert an empty line before a choice instruction block and insert an empty line after the block. The default is to insert.

Field: char are_lines_around_multiline_param

If not 0, insert an empty line before an instruction with a name and parameters occupying multiple lines and insert an empty line after the instruction. The default is to insert.

Field: char are_lines_inset_proc

[New in QSMM 1.19] If not 0, insert an empty line after a line with a ‘proc’ directive and insert an empty line before a line with an ‘end proc’ directive. The default is to insert.

Field: char do_print_comment_head

[New in QSMM 1.19] If not 0 and a procedure has a comment above itself, dump the comment. The default is to dump.

Field: char do_print_comment_tail

If not 0 and a procedure or the program contains a comment at its end, dump the comment. The default is to dump.

Field: int nline_around_proc

[New in QSMM 1.19] The number of empty lines to insert around a procedure. The default number of empty lines to insert is 2.

Field: struct qsmm_dump_instr_desc_s * dump_instr_desc_p

If this field is not NULL, it specifies input and output parameters of dumping assembler instructions by the function qsmm_instr_str. If this field is NULL, qsmm_instr_str uses default dumping parameters returned by the function qsmm_get_default_dump_instr_desc.