github.com/chenzhuoyu/iasm@v0.9.1/x86_64/assembler_test.go (about)

     1  package x86_64
     2  
     3  import (
     4      `fmt`
     5      `os`
     6      `os/exec`
     7      `strings`
     8      `testing`
     9  
    10      `github.com/chenzhuoyu/iasm/obj`
    11      `github.com/davecgh/go-spew/spew`
    12      `github.com/stretchr/testify/require`
    13  )
    14  
    15  func TestAssembler_Tokenizer(t *testing.T) {
    16      k := new(_Tokenizer)
    17      k.src = []rune(`movqorwhat $123, 123(%rax,%rbx), %rcx`)
    18      for {
    19          tk := k.next()
    20          if tk.tag == _T_end {
    21              break
    22          }
    23          spew.Dump(tk)
    24      }
    25  }
    26  
    27  func TestAssembler_Parser(t *testing.T) {
    28      p := new(Parser)
    29      v, e := p.Feed("movq " + strings.Join([]string {
    30          `$123`,
    31          `$-123`,
    32          `%rcx`,
    33          `(%rax)`,
    34          `123(%rax)`,
    35          `-123(%rax)`,
    36          `(%rax,%rbx,4)`,
    37          `1234(%rax,%rbx,4)`,
    38          `(,%rax,8)`,
    39          `1234(,%rax,8)`,
    40          `$(123 + 456)`,
    41          `(123 + 456)(%rax)`,
    42          `$'asd'`,
    43          `$'asdf'`,
    44          `$'asdfghj'`,
    45          `$'asdfghjk'`,
    46      }, ", "))
    47      require.NoError(t, e)
    48      spew.Dump(v)
    49  }
    50  
    51  func TestAssembler_Assemble(t *testing.T) {
    52      p := new(Assembler)
    53      e := p.Assemble(`
    54  .org 0x08000000
    55  .entry start
    56  
    57  msg:
    58      .ascii "hello, world\n"
    59  
    60  start:
    61      movl    $1, %edi
    62      leaq    msg(%rip), %rsi
    63      movl    $13, %edx
    64      movl    $0x02000004, %eax
    65      syscall
    66      xorl    %edi, %edi
    67      movl    $0x02000001, %eax
    68      syscall
    69  `)
    70      require.NoError(t, e)
    71      code := p.Code()
    72      base := p.Base()
    73      entry := p.Entry()
    74      spew.Dump(code)
    75      fmt.Printf("Image Base  : %#x\n", base)
    76      fmt.Printf("Entry Point : %#x\n", entry)
    77      fp, err := os.CreateTemp("", "macho_out-")
    78      require.NoError(t, err)
    79      err = obj.MachO.Write(fp, code, uint64(base), uint64(entry))
    80      require.NoError(t, err)
    81      err = fp.Close()
    82      require.NoError(t, err)
    83      err = os.Chmod(fp.Name(), 0755)
    84      require.NoError(t, err)
    85      println("Saved to", fp.Name())
    86      out, err := exec.Command(fp.Name()).Output()
    87      require.NoError(t, err)
    88      spew.Dump(out)
    89      require.Equal(t, []byte("hello, world\n"), out)
    90      err = os.Remove(fp.Name())
    91      require.NoError(t, err)
    92  }
    93  
    94  func TestAssembler_RIPRelative(t *testing.T) {
    95      p := new(Assembler)
    96      e := p.Assemble(`leaq 0x1b(%rip), %rsi`)
    97      require.NoError(t, e)
    98      spew.Dump(p.Code())
    99      require.Equal(t, []byte { 0x48, 0x8d, 0x35, 0x1b, 0x00, 0x00, 0x00 }, p.Code())
   100  }
   101  
   102  func TestAssembler_AbsoluteAddressing(t *testing.T) {
   103      p := new(Assembler)
   104      e := p.Assemble(`
   105  movq 0x1234, %rbx
   106  movq %rcx, 0x1234
   107  `)
   108      require.NoError(t, e)
   109      spew.Dump(p.Code())
   110      require.Equal(t, []byte {
   111          0x48, 0x8b, 0x1c, 0x25, 0x34, 0x12, 0x00, 0x00,
   112          0x48, 0x89, 0x0c, 0x25, 0x34, 0x12, 0x00, 0x00,
   113      }, p.Code())
   114  }
   115  
   116  func TestAssembler_LockPrefix(t *testing.T) {
   117      p := new(Assembler)
   118      e := p.Assemble(`lock cmpxchgq %r9, (%rbx)`)
   119      require.NoError(t, e)
   120      spew.Dump(p.Code())
   121      require.Equal(t, []byte { 0xf0, 0x4c, 0x0f, 0xb1, 0x0b }, p.Code())
   122  }
   123  
   124  func TestAssembler_SegmentOverride(t *testing.T) {
   125      p := new(Assembler)
   126      e := p.Assemble(`
   127  movq gs:0x30, %rcx
   128  movq gs:10(%rax), %rcx
   129  movq fs:(%r9), %rcx
   130  `)
   131      require.NoError(t, e)
   132      spew.Dump(p.Code())
   133      require.Equal(t, []byte {
   134          0x65, 0x48, 0x8b, 0x0c, 0x25, 0x30, 0x00, 0x00, 0x00,
   135          0x65, 0x48, 0x8b, 0x48, 0x0a,
   136          0x64, 0x49, 0x8b, 0x09,
   137      }, p.Code())
   138  }