Class AssemblyBuffer
Assembler
This is most useful when there is not a Program
available for assembly. If a program is
available, consider using GenericAssembler.assemble(Address, String...)
and reading the bytes
from the program. If not, or the program should not be modified, then the pattern of use is
generally:
Address start = space.getAdddress(0x00400000); Assembler asm = Assemblers.getAssembler(...); AssemblyBuffer buffer = new AssemblyBuffer(asm, start); buffer.assemble("PUSH R15"); buffer.assemble("PUSH R14"); buffer.assemble("PUSH R13"); ... byte[] bytes = buffer.getBytes(); state.setVar(start, bytes.length, true, bytes);
-
Constructor Summary
ConstructorDescriptionAssemblyBuffer
(Assembler asm, Address entry) Create a buffer with the given assembler starting at the given entry -
Method Summary
Modifier and TypeMethodDescriptionbyte[]
Assemble a line and patch into the bufferbyte[]
Assemble a line and append it to the bufferbyte[]
emit
(byte[] bytes) Append arbitrary bytes to the bufferbyte[]
getBytes()
Get the complete buffer of bytesgetNext()
Get the address of the "cursor" where the next instruction will be assembled
-
Constructor Details
-
AssemblyBuffer
Create a buffer with the given assembler starting at the given entry- Parameters:
asm
- the assemblerentry
- the starting address where the resulting code will be located
-
-
Method Details
-
getNext
Get the address of the "cursor" where the next instruction will be assembled- Returns:
- the address
-
assemble
public byte[] assemble(String line) throws AssemblySyntaxException, AssemblySemanticException, IOException Assemble a line and append it to the buffer- Parameters:
line
- the line- Returns:
- the resulting bytes for the assembled instruction
- Throws:
AssemblySyntaxException
- if the instruction cannot be parsedAssemblySemanticException
- if the instruction cannot be encodedIOException
- if the buffer cannot be written
-
assemble
public byte[] assemble(Address at, String line) throws AssemblySyntaxException, AssemblySemanticException, IOException Assemble a line and patch into the bufferThis will not grow the buffer, so the instruction being patched must already exist in the buffer. The typical use case is to fix up a reference:
AssemblyBuffer buf = new AssemblyBuffer(asm, entry); // ... Address jumpCheck = buf.getNext(); buf.assemble("JMP 0x" + buf.getNext()); // Template must accommodate expected jump distance // ... Address labelCheck = buf.getNext(); buf.assemble(jumpCheck, "JMP 0x" + labelCheck); buf.assemble("CMP ECX, 0"); // ...
This does not check that the patched instruction matches length with the new instruction. In fact, the buffer does not remember instruction boundaries at all. If verification is needed, the caller should check the lengths of the returned byte arrays for the template and the patch.
- Parameters:
at
- the address of the instruction to patchline
- the line- Returns:
- the resulting bytes for the assembled instruction
- Throws:
AssemblySyntaxException
- if the instruction cannot be parsedAssemblySemanticException
- if the instruction cannot be encodedIOException
- if the buffer cannot be written
-
emit
Append arbitrary bytes to the buffer- Parameters:
bytes
- the bytes to append- Returns:
- bytes
- Throws:
IOException
- if the buffer cannot be written
-
getBytes
public byte[] getBytes()Get the complete buffer of bytesHowever used, the bytes should be placed at the
entry
given at construction, unless the client is certain the code is position independent.- Returns:
- the bytes
-