Skip to the content.

asmline

note: run $ asmline, $ asmline --help or $ man asmline to view usage information

USAGE:
	asmline [OPTIONS]... FILE

DESCRIPTION: Assembles FILE into memory

Features:

Create binary file from assembly code

  1. $ asmline -o FILENAME path/to/file.asm to output the generated machine code into a binary file (FILENAME.bin)
     -o --object FILENAME
             Generates a binary file from path/to/file.asm called FILENAME.bin in the current directory.
    
  2. The above call will generate a binary file FILENAME.bin and the command below could be used to create an ELF file.
     $ objcopy \
     --input-target=binary \
     --globalize-symbol=FILENAME \
     --rename-section .data=.text \
     --output-target=elf64-x86-64 \
     FILENAME.bin FILENAME.o
    

Example

  1. Create an assembly program
     ; jump.asm
     mov rcx, 0x123
     jmp 0x4
     add rcx, 1
     mov rax, rcx
     ret
    
  2. Generate bin file with asmline
     $ asmline -o jump jump.asm 
    
  3. Generate a jump.o file from jump.bin
     $ objcopy \
     --input-target=binary \
     --redefine-sym _binary_jump_bin_start=jump \
     --rename-section .data=.text \
     --output-target=elf64-x86-64 \
     jump.bin jump.o 
    
  4. Now we can run $ objdump on jump.o to see the symbols in the ELF file
     $ objdump -t jump.o
    
     jump.o:     file format elf64-x86-64
    
     SYMBOL TABLE:
     0000000000000000 l    d  .text	0000000000000000 .text
     0000000000000000 g       .text	0000000000000000 jump
     000000000000000f g       .text	0000000000000000 _binary_jump_bin_end
     000000000000000f g       *ABS*	0000000000000000 _binary_jump_bin_size
    
     $ objdump -D jump.o 
        
     jump.o:     file format elf64-x86-64
        
        
     Disassembly of section .text:
        
     0000000000000000 <jump>:
        0:   b9 23 01 00 00          mov    $0x123,%ecx
        5:   eb 04                   jmp    b <jump+0xb>
        7:   48 83 c1 01             add    $0x1,%rcx
        b:   48 89 c8                mov    %rcx,%rax
        e:   c3                      ret
        
    

$ asmline -p path/to/file.asm to write the generated machine code from path/to/file.asm to stdout

-p --print
        The corresponding machine code will be printed to stdout in hex form.
        Output is similar to `objdump`: Byte-wise delimited by space and linebreaks after 7 bytes.
        If -c is given, the chunks are delimited by '|' and each chunk is on one line.

Example

$ asmline -p jump.asm
b9 23 01 00 00 
eb 04 
48 83 c1 01 
48 89 c8 
c3 

$ asmline -P FILENAME path/to/file.asm to write the generated machine code from path/to/file.asm to FILENAME

 -P, --printfile FILENAME
         The corresponding machine code will be printed to FILENAME in binary form.
         Can be set to '/dev/stdout' to write to stdout (similar to -p, --print).

Example

$ asmline -Pjump.bin jump.asm && xxd -p jump.bin 
b923010000eb044883c1014889c8c3

Chunk size fitting

$ asmline -c CHUNK_SIZE>1 path/to/file.asm to appy chunk size fitting when assembling path/to/file.asm.

 -c --chunk CHUNK_SIZE>1
         Sets a given CHUNK_SIZE boundary in bytes. Nop padding will be used to 
         ensure no instruction opcode crosses the specified CHUNK_SIZE boundary.

Note: A specific chunk size could be specified for instruction alignment (chunk sizes must be greater than 1), AssemblyLine will ensure no instruction opcode crosses the chunk size boundary by applying nop padding.

Example

$ asmline --chunk 5 jump.asm -p
b9 23 01 00 00 |
eb 04 0f 1f 00 |
48 83 c1 01 90 |
48 89 c8 c3 

Note: we see that every instruction for NOP’ed to fit the chunk of size 5.

Executing machine code directly from memory

$ asmline --return path/to/file.asm to directly execute path/to/file.asm given the following options:

-r[=LEN], --return[=LEN]
    Assembles given code. Then executes it with six parameters to heap-allocated memory.
    Each pointer points to an array of LEN 64-bit elements which can be dereferenced in the asm-code, where LEN defaults to 10.
    After execution, it prints out the contents of the return (rax) register and frees the heap-memory.

--rand 
     implies -r and will additionally initialize the memory from with random data. -r=11 can be used to alter LEN.

Example

; add_one.asm
mov rcx, 0x123
add rcx, 1
mov rax, rcx
ret

Execute the file and get return value with asmline

$ asmline -r add_one.asm
the value is 0x124

Example 2: Executing an assembly program with arguments from memory example

Note: The -r[=LEN] will execute assembly code with 6 parameters consisting of uint64 arrays with length LEN, defaulting to LEN=10. That means that rdir9 can be dereferenced in the assembly file.

; adelaide.asm
mov [rdi], 0xADE1A1DE
mov rax, 0xADE1A1DE
mov [rsi], rax
mov [rdx], rax
mov [rcx], rax          ; LEN must be min 1 for this to work, as we access arg3[0]
mov [rcx + 0x08], rax   ; LEN must be min 2 for this to work, as we access arg3[1]
mov [r8], rax
mov [r9], rax
ret
$ asmline -r=2 adelaide.asm
the value is 0xade1a1de

NOTE: The return value is obvious, but note that the program did not segfault when dereferencing the parameters rdir9.

Different Modes of Assembly

The settings below allow the user to control the aforementioned behavior.

Set SIB register swap to NASM

  1. $ asmline --nasm-sib-index-base-swap path/to/file.asm to ensure the generated machine code from path/to/file.asm matches nasm
     --nasm-sib-index-base-swap
             In SIB addressing if the index register is esp or rsp then the base and index registers
             will be swapped (this is enabled by default).
             That is: "lea r15, [rax+rsp]" interpreted as "lea r15, [rsp+rax]" -> 4c 8d 3c 04
                      "lea r15, [rsp+rsp]" will produce an error  (base and index cannot be swapped)
    

Set SIB register swap to STRICT

  1. $ asmline --strict-sib-index-base-swap path/to/file.asm to ensure the generated machine code from path/to/file.asm is in an ‘as is’ state
     --strict-sib-index-base-swap
             In SIB addressing the base and index registers will not be swapped even if the
             index register is esp or rsp.
             That is: "lea r15, [rax+rsp]" will be interpreted as "lea r15, [rax+riz]" -> 4c 8d 3c 20
                      riz is a pseudo-register evaluated by GCC to constant 0 and therefore cannot be
                      used in assemblyline as a string ie. assembling "lea r15, [rax+riz]" is invalid
                      "lea r15, [rsp+rsp]" will also produce an error (invalid instruction)
    

Set SIB no base to NASM

  1. $ asmline --nasm-sib-no-base path/to/file.asm to ensure the generated machine code from path/to/file.asm matches nasm
     --nasm-sib-no-base
             In SIB addressing if there is no base register present and scale is equal to 2; 
         the base register will be set to the index register and the scale will be reduced to 1.
             (this is enabled by default).
             That is: "lea r15, [2*rax]" will be interpreted as "lea r15, [rax+1*rax]" -> 4c 8d 3c 00
    

Set SIB no base to STRICT

  1. $ asmline --strict-sib-no-base path/to/file.asm to ensure the generated machine code from path/to/file.asm is in an ‘as is’ state
     --strict-sib-no-base
             In SIB addressing when there is no base register present the index and scale 
         would not change regardless of scale value.
             That is: "lea r15, [2*rax]" will be interpreted as "lea r15, [2*rax]" -> 4c 8d 3c 45 00 00 00 00
    

Set mov immediate to NASM

  1. $ asmline --nasm-mov-imm path/to/file.asm to ensure the generated machine code from path/to/file.asm matches nasm
     --nasm-mov-imm
             Enables nasm-style mov-immediate register-size optimization.
             ex: if immediate size for mov is less than or equal to max signed 32-bit assemblyline
                 will emit code to mov to the 32-bit register rather than 64-bit.
             That is: "mov rax,0x7fffffff" as "mov eax,0x7fffffff" -> b8 ff ff ff 7f
             note: rax got optimized to eax for faster immediate to register transfer and
                   produces a shorter instruction. 
    

Set mov immediate to STRICT

  1. $ asmline --strict-mov-imm path/to/file.asm to ensure the generated machine code from path/to/file.asm is in an ‘as is’ state
     --strict-mov-imm
             Disables nasm-style mov-immediate register-size optimization.
             ex: even if immediate size for mov is less than or equal to max signed 32-bit assemblyline.
                 will pad the immediate to fit 64-bit
             That is: "mov rax,0x7fffffff" as "mov rax,0x000000007fffffff"
                       -> 48 b8 ff ff ff 7f 00 00 00 00
             note: rax got optimized to eax for faster immediate to register transfer
                   and produces a shorter instruction.
    

Set mov immediate to SMART

  1. $ asmline --smart-mov-imm path/to/file.asm to ensure the generated machine code from path/to/file.asm can manually be set to
    disable nasm mode (this is enabled by default).
     --smart-mov-imm
             The immediate value will be checked for leading 0's.
             Immediate must be zero padded to 64-bits exactly to ensure it will not optimize.
             This is currently set as default.
             ex: "mov rax, 0x000000007fffffff" ->  48 b8 ff ff ff 7f 00 00 00 00
                 "mov rax, 0x7fffffff" -> b8 ff ff ff 7f
    

Set all SIB options to NASM

  1. $ asmline --nasm-sib path/to/file.asm to ensure the generated machine code with SIB from path/to/file.asm matches nasm
     --nasm-sib
            equivalent to --nasm-sib-no-base --nasm-sib-index-base-swap
    

Set all SIB options to STRICT

  1. $ asmline --strict-sib path/to/file.asm to ensure the generated machine code with SIB from path/to/file.asm is in an ‘as is’ state
     --strict-sib
               equivalent to --strict-sib-no-base --strict-sib-index-base-swap
    

Set all options to NASM

  1. $ asmline --nasm path/to/file.asm to ensure the generated machine code from path/to/file.asm matches nasm
     -n, --nasm
            equivalent to --nasm-mov-imm --nasm-sib
    

Set all options to STRICT

  1. $ asmline --strict path/to/file.asm to ensure the generated machine code from path/to/file.asm is in an ‘as is’ state
     -t, --strict
               equivalent to --strict-mov-imm --strict-sib