Say hello to x86_64 Assembly [part 5]

http://0xax.blogspot.sg/2014/11/say-hello-to-x8664-assembly-part-5.html

It is a fifth part of Say hello to x86_64 Assembly and here we will look at macros. It will not be blog post about x86_64, mainly it will be about nasm assembler and it's preprocessor. If you're interesting in it read next. 

Macros


NASM supports two form of macro:

  • single-line
  • multiline

All single-line macro must start from %define directive. It form is following: 

  %define macro_name(parameter) value
view rawgistfile1.asm hosted with ❤ by GitHub

Nasm macro behaves and looks very similar as in C. For example, we can create following single-line macro: 

  %define argc rsp + 8
  %define cliArg1 rsp + 24
view rawgistfile1.asm hosted with ❤ by GitHub

and than use it in code: 

  ;;
  ;; argc will be expanded to rsp + 8
  ;;
  mov rax, [argc]
  cmp rax, 3
  jne .mustBe3args
view rawgistfile1.asm hosted with ❤ by GitHub

Multiline macro starts with %macro nasm directive and end with %endmacro. It general form is following: 

  %macro number_of_parameters
  instruction
  instruction
  instruction
  %endmacro
view rawgistfile1.asm hosted with ❤ by GitHub

For example: 

  %macro bootstrap 1
  push ebp
  mov ebp,esp
  %endmacro
view rawgistfile1.asm hosted with ❤ by GitHub

And we can use it: 

  _start:
  bootstrap
view rawgistfile1.asm hosted with ❤ by GitHub

For example let's look at PRINT macro: 

  %macro PRINT 1
  pusha
  pushf
  jmp %%astr
  %%str db %1, 0
  %%strln equ $-%%str
  %%astr: _syscall_write %%str, %%strln
  popf
  popa
  %endmacro
   
  %macro _syscall_write 2
  mov rax, 1
  mov rdi, 1
  mov rsi, %%str
  mov rdx, %%strln
  syscall
  %endmacro
view rawgistfile1.asm hosted with ❤ by GitHub

Let's try to go through it macro and understand how it works: At first line we defined PRINT macro with one parameter. Than we push all general registers (with pusha instruction) and flag register with (with pushf instruction). After this we jump to %%astr label. Pay attention that all labels which defined in macro must start with %%. Now we move to__syscall_write macro with 2 parameter. Let's look on __syscall_write implementation. You can remember that we use writesystem call in all previous posts for printing string to stdout. It looks like this: 

  ;; write syscall number
  mov rax, 1
  ;; file descriptor, standard output
  mov rdi, 1
  ;; message address
  mov rsi, msg
  ;; length of message
  mov rdx, 14
  ;; call write syscall
  syscall
view rawgistfile1.asm hosted with ❤ by GitHub

In our __syscall_write macro we define first two instruction for putting 1 to rax (write system call number) and rdi (stdout file descriptor). Than we put %%str to rsi register (pointer to string), where %%str is local label to which is get first parameter of PRINT macro (pay attention that macro parameter access by $parameter_number) and end with 0 (every string must end with zero). And %%strlen which calculates string length. After this we call system call with syscall instruction and that's all. 

Now we can use it: 

  label: PRINT "Hello World!"
view rawgistfile1.asm hosted with ❤ by GitHub

Useful standard macros


NASM supports following standard macros:

STRUC

We can use STRUC and ENDSTRUC for data structure defintion. For example: 

  struc person
  name: resb 10
  age: resb 1
  endstruc
view rawgistfile1.asm hosted with ❤ by GitHub

And now we can make instance of our structure: 

  section .data
  p: istruc person
  at name db "name"
  at age db 25
  iend
   
  section .text
  _start:
  mov rax, [p + person.name]
view rawgistfile1.asm hosted with ❤ by GitHub

%include

We can include other assembly files and jump to there labels or call functions with %include directive. 

Conclusion


It was a fifth part of series 'say hello to x64 assembly', if you will have a questions/suggestions write me a comment or ping me at twitter for discussing. In next part we will talk about difference between Intel syntax and AT&T and look at gas assembly. If you're interesting in some additional themes about assembly and x86_64 programming write me a comment and I will try to write blog post about it in near time. 

All another parts you can find - here

All source code you can find as every time - here

English is not my first language, so you'll find mistakes in blog post please write me in comments or drop me email . 

posted on 2015-09-14 15:40  Maxwell Hu  阅读(138)  评论(0编辑  收藏  举报