NASM
Last updated
Was this helpful?
Last updated
Was this helpful?
3.1 NASM
NASM is an assembler that we will use. To make things easier, we will use the project. It is a collection of macros, includes, and examples to help NASM programmers develop applications.
How to install:
Download and extract it to C:\nasmx
Add the bin to environment variables
Run setpath.bat
To work with demos:
Comment the following line in C:\nasmx\demos\windemos.inc
Add directly below it the following code
Open C:\nasmx\demos\win32\DEMO1
To use the assembler, we run the following command:
To link the object files, use golink, which is located in the same package (NASMX) when NASM is downloaded:
A prompt will show up if the operations are successful
3.2 ASM Basics
High-level functions such as strcpy() are made of multiple ASM instructions put together to perform the given operation (copy of 2 strings)
The simplest assembly instruction is MOV that moves data from one location to another in memory.
Most instructions have 2 operands and fall into one of the following classes:
Data Transfer
Arithmetic
Control Flow
Other
MOV
ADD
CALL
STI
XCMG
SUB
RET
CLI
PUSH
MUL
LCOP
IN
POP
XOR
Jcc
OUT
The following is an example of a simple assembly code that sums 2 numbers:
3.2.1 Intel vs AT&T
Depending on the architectural syntax, instructions and rules may vary. For example, the source and the destination operands may be in different position.
example:
Intel (Windows)
AT&T(Linux)
Assembly
MOV EAX, 8
MOVL $8, %EAX
Syntax
<instruction><destination><source>
<instruction><source><destination>
In AT&T syntax, % is put before registers names and $ is put before numbers. Another thing to notice is that AT&T adds a suffix to t he instruction, which defines the operand size:
Q (quad - 64 bits)
L (long - 32 bits)
W (word - 16 bits)
B (byte - 8 bits)
3.2.2 PUSH Instruction
As it has been said before, PUSH stores a value to the top of the stack, causing the stack to be adjusted by -4 bytes (on 32 bit systems): -0x04
Operation : PUSH 0x12345678
| | Before PUSH | After PUSH | | |-|-------------|------------| | |Lower memory address|||| || | 12345678 |<- Top of the Stack| |Top of the Stack -> | 00000001 | 00000001 | | | | 00000001 | 00000001 | | | | 00000001 | 00000001 | | | | 00000001 | 00000001 | | |Higher memory address|||||
Another interesting fact: PUSH 0x123456789 can be analogous to some other operations, for example:
3.2.3 POP Instruction
As it has been said before, POP stores a value to the top of the stack, causing the stack to be adjusted by +4 bytes (on 32 bit systems): +0x04
Operation : POP reg
| | Before PUSH | After PUSH | | |-|-------------|------------| | |Lower memory address|||| |Top of the Stack -> | 12345678 | || || 00000001 | 00000001 | <- Top of the Stack | | | 00000001 | 00000001 | | | | 00000001 | 00000001 | | | | 00000001 | 00000001 | | |Higher memory address|||||
Another interesting fact: POP EAX can be analogous to some other operations, for example:
3.2.4 CALL Instruction
Subroutines are implemented by using CALL and RET instruction pair.
The CALL instruction pushes the current instruction pointer (EIP) to the stack and jumps to the function address specified.
Whenever the function executes the RET instruction, the last element is popped from the stack, and the CPU jumps to the address.
Example of CALL in Assembly:
The following is an example of how to call a procedure. This example begins at proc_2:
Is the same with
You can learn more about assembly online by yourself.