++ed by:

146 PAUSE users
121 non-PAUSE users.

Nicholas Clark
and 1 contributors

TEST FOR B::Assembler.pm AND B::Disassembler.pm


The general idea is to test by assembling a choice set of assembler instructions, then disassemble them, and check that we've completed the round trip. Also, error checking of Assembler.pm is tested by feeding it assorted errors.

Since Assembler.pm likes to assemble a file, we comply by writing a text file. This file contains three sections:

  testing operand categories
  use each opcode
  erronous assembler instructions

An "operand category" is identified by the suffix of the PUT_/GET_ subroutines as shown in the %Asmdata::insn_data initialization, e.g. opcode ldsv has operand category svindex:

   insn_data{ldsv} = [1, \&PUT_svindex, "GET_svindex"];

Because Disassembler.pm also assumes input from a file, we write the resulting object code to a file. And disassembled output is written to yet another text file which is then compared to the original input. (Erronous assembler instructions still generate code, but this is not written to the object file; therefore disassembly bails out at the first instruction in error.)

All files are kept in memory by using TIEHASH.


An error where Assembler.pm and Disassembler.pm agree but Assembler.pm generates invalid object code will not be detected.

Due to the way this test has been set up, failure of a single test could cause all subsequent tests to fail as well: After an unexpected assembler error no output is written, and disassembled lines will be out of sync for all lines thereafter.

Not all possibilities for writing a valid operand value can be tested because disassembly results in a uniform representation.


New opcodes are added automatically.

A new operand category will cause this program to die ("no operand list for XXX"). The cure is to add suitable entries to %goodlist and %badlist. (Since the data in Asmdata.pm is autogenerated, it may also happen that the corresponding assembly or disassembly subroutine is missing.) Note that an empty array as a %goodlist entry means that opcodes of the operand category do not take an operand (and therefore the corresponding entry in %badlist should have one). An undef entry in %badlist means that any value is acceptable (and thus there is no way to cause an error).

Set $dbg to debug this test.