8.2.7 Assembler
as
nasm
ndisasm
(3 commands). Assembler, an alternative "native assembler" and a disassembler. Send in your newbie examples how to use those :) E.g.: ndisasm /bin/sh |more produces a long output of "assembler mnemonics" from a binary on my system (/bin/sh in this example) but I cannot understand it anyway :( To learn more about nasm, you may want to see: file:///usr/share/doc/nasm-doc-0.98/html/nasmdoc0.html
Example Intel assembly for Linux 2.2.17 or higher:
;; hello.asm: Copyright (C) 2001 by Brian Raiter, under the GNU
;; General Public License (version 2 or later). No warranty.
BITS 32
org 0x05936000
db 0x7F, "ELF"
dd 1
dd 0
dd $$
dw 2
dw 3
_start: inc eax ; 1 == exit syscall no.
mov dl, 13 ; set edx to length of message
cmp al, _start - $$
pusha ; save eax and ebx
xchg eax, ebx ; set ebx to 1 (stdout)
add eax, dword 4 ; 4 == write syscall no.
mov ecx, msg ; point ecx at message
int 0x80 ; eax = write(ebx, ecx, edx)
popa ; set eax to 1 and ebx to 0
int 0x80 ; exit(bl)
dw 0x20
dw 1
msg: db 'hello, world', 10
After saving this to a plain-text file hello.asm, I can build it to an output file "hello" and make the output executable using the command:
nasm -f bin -o hello hello.asm && chmod +x hello
and execute it using:
./hello
The example above is borrowed from http://www.muppetlabs.com/~breadbox/software/tiny/.
Why would somebody use assembler? After building from assembler, this example executable is 56 bytes on my system. The "C" language example with identical functionality (see one page above) is 13.7 kB.
Here is brief info to help me understand the above program:
";" marks comments (to the end of the line).
"msg:" -- is an example of a label (like in FORTRAN).
org (="origin")--declares where in the memory the program begins (after it is loaded to memory for execution).
db, dd, dw are nasm "pseudoinstructions" used to insert initialized data into the output file.
"$" evaluates to the assembly position at the beginning of the line containing the expression; so you can code an infinite loop using "JMP $". "$$" evaluates to the beginning of the current section.
The general-purpose 32-bit registers in the 80x86 ("Intel") processor are: EAX, EBX, ECX, EDX, ESI, EDI, EBP, and ESP. (The "E" stands for extended. It is there because the processor can instead "overlay" the registers and treat them as 16-bit registers with names: AX, BX, CX, CX, SI, DI, BP, and SP. Still underlying those, there are also eight 8-bit registers: AL, AH, BL, BH, CL, CH, DL, DH. Here, the "L" and "H" stand for "high" and "low" byte.).
Mnemonics for some common 80x86 processor instructions:
Name Syntax Comment
NOP NOP No operation (do nothing).
MOV mov destination, source Move (copy, set)data.
XCHG XCHG operand1,operand2 Exchange the values.
CMP CMP operand1,operand2 Compare the two operands.
PUSH PUSH source Push onto stack.(Place the value on stack and increment the stack pointer).
PUSHF PUSHF Push flags.
PUSHA PUSHA Push all general-purpose registers.
POP POP destination Pop from stack(take the value from stack, and decrement the stack pointer). Pop is reverse to push.
POPF POPF Pop flags.
POPA POPA Pop all general-purpose registers.
INC INC operand Increment (increase by 1).
DEC DEC operand Decrement (decrease by 1).
ADD ADD Dest,Source Add.
ADC ADC Dest,Source Add with carry.
SUB SUB Dest,Source
* License

