Dividing and Conquering
Book: Assembly Language step by step
Complexity kills programs.
Remember to use comment headers.(Comment is very very important!)
More Than 25 lines and you're doing too much in one procedure.Split it up.
Calling and Returning
call LoadBuff
...
loadBuff:
push eax ; a1
push ebx ; a2
push edx ; a3
mov eax, 3 ; sys_read call
mov ebx, 0 ; File Descriptor 0: stdin
mov ecx, Buff ; offset of the buffer to read to
mov edx, BUFFLEN ; number of bytes to read at one pass
int 80h ; sys_read
mov ebp, eax
xor ecx, ecx
pop edx ; b1
pop ebx ; b2
pop eax ; b3
ret
- a1~a3 and b1~b3 are store of stack
- "xor ecx, ecx" is faster than "mov ecx, 0"
Saving the Caller's Registers
pushad
...
popad
Table Tricks
DumpLin db " 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 "
DUMPLEN equ $-DumpLin
ASCLin db "|................|", 10
ASCLEN equ $-ASCLin
FULLLEN equ $-DumpLin
lea edi, [edx*2+edx] ; trick to calculate 3*edx
Local Labels and the Lengths of Jumps
Scan:
xor eax, eax
...
.modTest:
test esi, 0000000Fh
...
- "Scan" is a nonlocal label.(global label)
- ".modTest" is a local label.
- Local labels are local to the first nonlocal label that precedes them in the code.
- A local label cannot be referenced higher in the source code file than the global label that owns it.
- Local labels are not accessible as breakpoints from the command-line interface of GDB.
- Good habits: local labels and all jumps to them should occur within a single screen of code.
Type of Jumps
jne Scan ; Short jump, to within 127 bytes in either direction
jne near Scan ; Near jump, anywhere in the current code segment
Building External Procedure Libraries
Each executable file can only contain one _start: label. External modules do not contain _start:
External modules do not return to Linux.(Only the main program module can make sys_exit INT 80h call)
main-program.asm:
section .text
extern ClearLine
global _start
_start:
...
call ClearLine
...
lib.asm:
section .text
global ClearLine
...
ClearLine:
...
Rules:
- "extern" to declare all the labels that don't belong to the current file.
- "global" to declare all the labels in the current file needed by other files.
Simple Cursor Control in the Linux Console
[section .data]
PositionTerm db 27, "[01;01H" ; <ESC>[<Y>;<X>H -This sequences move the cursor to (X, Y)
ClearTerm db 27, "[2J" ; <ESC>[2J -This sequences clears the display.
GreenBack db 27, "[42m" ; <ESC>[42m -turns the consoles background green
For more details about console escape codes: man console_codes
Creating and Using Macros
%macro WriteStr 2 ; 2 arguments
push eax
push ebx
mov ecx, %1 ; %1 invokes the first argument (Prompt)
mov edx, %2 ; %2 invokes the second argument (PROMPTLEN)
mov eax, 4
mov edx, 1
int 80h
pop ebx
pop eax
%endmacro
....
....
WriteStr Prompt, PROMPTLEN
; When a macro is invoked, its arguments are separated by commas.
Local Labels Within Macros
%macro UpCase 2
mov edx, %1
mov ecx, %2
%%IsLC:
cmp byte [edx+ecx-1], 'a'
jb %%Bump
cmp byte [edx+ecx-1], 'z'
ja %%Bump
sub byte [edx+ecx-1], 20h
%%Bump:
dec ecx
jnz %%IsLC
%endmacro
Macro Libraries As Include Files
%include "mylib.mac"