这是Say hello to x86_64 Assembly的第五部分,下面我们将介绍宏。它不会是关于x86_64的博客文章,主要是关于nasm汇编程序及其预处理器的。如果你对它感兴趣,请看下一篇。
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支持两种形式的宏: -单行 -多行 所有单行宏都必须从%define指令开始。其形式如下:
NASM supports two form of macro:
All single-line macro must start from %define directive. It form is following:
Nasm宏的行为和外观与C中的非常相似。例如,我们可以创建以下单行宏:
Nasm macro behaves and looks very similar as in C. For example, we can create following single-line macro:
在代码中使用它:
and than use it in code:
多行宏以%macro nasm指令开头,以%endmacro结尾。一般形式如下:
Multiline macro starts with %macro nasm directive and end with %endmacro. It general form is following:
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 write system call in all previous posts for printing string to stdout. It looks like this:
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:
Useful standard macros
NASM支持以下标准宏:
NASM supports following standard macros:
struc
我们可以使用'STRUC'和'ENDSTRUC'来定义数据结构。例如:
We can use STRUC and ENDSTRUC for data structure defintion. For example:
现在我们可以举例说明我们的结构:
And now we can make instance of our structure:
我们可以包含其他程序集文件并跳转到其中的标签或使用%include指令调用函数。
We can include other assembly files and jump to there labels or call functions with %include directive.