Labels Definition valid characters in labels are: letters, numbers, _, $, #, @, ~,., and ? first character can be: letter, _, ? and. (. has a special meaning) label can be prefixed with a $ to indicate that it is intended to be read as an identifier and not a reserved word Example: if some other module you are linking with defines a symbol called eax, you can refer to $eax in NASM code to distinguish the symbol from the register.
Flags Flags as a whole is a single 16-bit register buried inside the CPU. Of those 16 bits, 9 are actually used as flags on the x86. A flag is a single bit of information whose meaning is independent from any other bit. Each of the Flags register's nine flags has a two-letter symbol by which most programmers know them. OF— The Overflow flag is set when the result of an operation becomes too large to fit in the operand it originally occupied. SF— The Sign flag becomes set when the result of an operation forces the operand to become negative. ZF— The Zero flag becomes set when the results of an operation become zero. CF— The Carry flag is by far the most useful flag in the Flags register, and the one you will have to pay attention to most. If the result of an arithmetic or shift operation "carries out" a bit from the operand, CF becomes set.
Jcc: Conditional Branch JE/JZ – Jumps if ZF = 1 (Zero Flag = 1) JNE/JNZ – Jumps if ZF = 0 JLE/JNG (Jump Less Equal, Jump Not Greater) – ZF = 1 or SF ≠ OF JG/JNLE (Jump Greater/Jump Not Less Equal) ZF = 0 and SF = OF JL/JNGE (Jump Less/Jump Not Greater Equal) – SF ≠ OF JGE/JNL (Jump Greater Equal/Jump Not Less) SF = OF JS – Jumps if SF = 1 (Sign Flag = 1) JNS – Jumps if SF = 0
Sections Hold the bulk of object file information for the linking view: instructions, data, symbol table, relocation information, and so on. Important types:.bss - This section holds uninitialized data that contribute to the program’s memory image. The section occupies no file space..data and.data1 - These sections hold initialized data that contribute to the program’s memory image. rodata and.rodata1 - These sections hold read-only data that typically contribute to a non-writable segment in the process image..text - This section holds the ‘‘text,’’ or executable instructions, of a program.
Pseudo-instructions Pseudo-instructions are things which, though not real x86 machine instructions, are used in the instruction field anyway because that's the most convenient place to put them. The notion of type in assembly language is almost wholly a question of size. You can define named variables in your assembly language programs using such pseudo-instructions as DB and DW. Initialized data: something that comes with a value, and not just a box that will accept a value at some future time. A variable is defined by associating an identifier with a data definition pseudo-instruction, such as DB, DW, DD, etc.
RESB, RESW, RESD, RESQ AND REST: declaring uninitialized storage space Example: 1. buffer: resb 64 ; reserve 64 bytes 2. word_var: resw 1 ; reserve a word 3. real_array resq 10 ; array of ten real numbers Note: you can not make any assumption about values of a storage space cells.
EQU : defining constants EQU defines a symbol to a given constant value: when EQU is used, the source line must contain a label. The action of EQU is to define the given label name to be the value of its (only) operand. This definition cannot changed later. Example: FOO: EQU 1 ; FOO = 1
TIMES : Repeating Instructions or Data The TIMES prefix causes the instruction to be assembled multiple times ( partly NASM's equivalent of the DUP). The argument to TIMES is not just a numeric constant, but a numeric expression. TIMES can be applied to ordinary instructions, so you can code trivial unrolled loops. Example: zerobuf: times 64 db 0 0 0 0 64
Effective Addresses An effective address is any operand to an instruction which references memory. Effective addresses, in NASM, have a very simple syntax: they consist of an expression evaluating to the desired address, enclosed in square brackets. Examples: wordvar: dw 0x5A, 0x39 mov ax,[wordvar] ; ax = 0x005A (In Little Endian Format ) mov ax,[wordvar+1] ; ax = 0x3900
Constants NASM understands four different types of constant: numeric, character, string and floating points. 1. numeric constants - A numeric constant is simply a number. NASM allows to specify numbers in a variety of number bases, in a variety of ways: suffix H, Q and B for hex, octal and binary, etc. Examples: mov ax,100 ; decimal mov ax,0a2h ; hex mov ax,777q ; octal mov ax,10010011b ; binary
2. Character Constants A character constant consists of up to 4 characters enclosed in either single or double quotes. A character constant with more than one character will be arranged with little- endian order in mind. Examples: mov eax,'abcd' The constant generated is not 0x61626364, but 0x64636261, so that if you were then to store the value into memory, it would read abcd rather than dcba. That way, it is stored “backwards” in eax.
3. String Constants String constants are only acceptable to some pseudo-instructions, namely the DB family and INCBIN. A string constant looks like a character constant, only longer. It is treated as a concatenation of maximum-size character constants for the conditions. Examples: db 'hello' ; string constant db 'h','e','l','l','o' ; equivalent character constants
Advanced Instructions MUL - Unsigned Integer Multiply IMUL - Signed Integer Multiply MUL/IMUL r/m MUL performs unsigned integer multiplication, and IMUL perform signed integer multiplication.. The other operand to the multiplication, and the destination operand are implicit, in the following way: For MUL r/m8, AL is multiplied by the given operand. the product is stored in AX. For MUL r/m16, AX is multiplied by the given operand. The product is stored in DX:AX. For MUL r/m32, EAX is multiplied by the given operand. The product is stored in EDX:EAX.
JMP:Unconditional Jump JMP imm/r/m16/m32 JMP SHORT imm JMP FAR mem/mem32 JMP jumps to a given address. The address may be specified as an absolute segment and offset, or as a relative jump within the current segment. The JMP r/m forms execute a near jump (within the same segment ), loading the destination address out of memory or out of a register, and has limited range of 32767 (16 bits). The keyword NEAR may be specified, for clarity, in these forms, but is not necessary. JMP SHORT imm has a maximum range of 128 bytes, since the displacement is specified as only 8 bits, but takes up less code space. NASM does not choose when to generate JMP SHORT for you: you must explicitly code SHORT every time you want a short jump. The JMP FAR mem forms execute a far jump by loading the destination address out of memory. The address loaded consists of 16 or 32 bits of offset (depending on the operand size), and 16 bits of segment.
Loop definition: LOOP, LOOPE, LOOPZ, LOOPNE, LOOPNZ: loop with counter * for all the possible variants of operands look at NASM manual, B.4.142 Example: mov ax, 1 mov cx, 3 my_ loop: add ax, ax loop my_ loop, cx 1. decrements its counter register (in this case it is CX register) 2. if the counter does not become zero as a result of this operation, it jumps to the given label Note: counter register can be either CX or ECX - if one is not specified explicitly, the BITS setting dictates which is used. LOOPE (or its synonym LOOPZ ) adds the additional condition that it only jumps if the counter is nonzero and the zero flag is set. Similarly, LOOPNE (and LOOPNZ ) jumps only if the counter is nonzero and the zero flag is clear.
SHL, SHR : Bitwise Logical Shifts SHL r/m8/m16/m32 1/CL/imm8 SHR r/m8/m16/m32 1/CL/imm8 SHL and SHR perform a logical shift operation on the given source/destination (first) operand. The vacated bits are filled with zero. The number of bits to shift by is given by the second operand. The shifted bit enters the Carry Flag. Example: mov CL, 3 mov AL,10110111b ; AL = 10110111 shr AL, 1 ; shift right 1 AL = 01011011 shr AL, CL; shift right 3 AL = 00001011 Perform division/multiplication with 2.
SAL, SAR : Bitwise Arithmetic Shifts SAL r/m8/m16/m32 1/CL/imm8 SAR r/m8/m16/m32 1/CL/imm8 SAL and SAR perform an arithmetic shift operation on the given source/destination (first) operand. The vacated bits are filled with zero for SAL, and with copies of the original high bit of the source operand for SAR. Example: mov CL, 3 mov AL,10110111b ; AL = 10110111 sar AL, 1 ; shift right 1 AL = 11011011 sar AL, CL; shift right 3 AL = 11111011
ROL, ROR : Bitwise Rotate ROL r/m8/m16/m32 1/CL/imm8 ROR r/m8/m16/m32 1/CL/imm8 ROL and ROR perform a bitwise rotation operation on the given source/destination (first) operand. Thus, for example, in the operation ROL AL,1, an 8-bit rotation is performed in which AL is shifted left by 1 and the original top bit of AL moves round into the low bit. Example: mov CL, 3 mov BH,10110111b ; BH = 10110111 rol BH, 01 ; rotate left 1 bit BH = 01101111 rol BH, CL; rotate left 3 bits BH = 01111011
RCL, RCR : Bitwise Rotate through Carry Bit RCL r/m8/m16/m32 1/CL/imm8 RCR r/m8/m16/m32 1/CL/imm8 RCL and RCR perform a 9-bit, 17-bit or 33-bit bitwise rotation operation, involving the given source/destination (first) operand and the carry bit. Thus, for example, in the operation RCL AL,1, a 9-bit rotation is performed in which AL is shifted left by 1, the top bit of AL moves into the carry flag, and the original value of the carry flag is placed in the low bit of AL. Example: mov BH,10110111b ; BH = 10110111 ;CF = 0 rcl BH, 01 ; rotate left 1 bit BH = 01101110 ;CF = 1