Assembly Language
Assembly Language
SS
CS
DS
ES
FS
GS
EIP
IP
EFLAGSFLAGS
Moving On
mov
mov
mov
mov
mov
mov
mov
<dest>, <src>
eax, dwMyVar
eax, 65h
eax, 0FFFFFFFFh
eax, [ebx]
eax, [eax+4]
dwMyVar, esi
rithmetic
add eax, ebx
sub eax, ebx
mul edx
imul edx
inc
eax
dec eax
adc, sbb, neg
eax += ebx;
eax -= ebx;
eax *= edx;
(signed version)
eax++;
eax--;
A House Divided
[i]div <divisor>
Dividend Divisor
AX
8 bits
DX:AX 16 bits
EDX:EAX 32 bits
Quotient
AL
AX
EAX
Remainder
AH
DX
EDX
and
or
xor
not
or
jz
eax, ebx
eax, 3
ecx, 69h
ebx
ah,ah
lbl_AHIsZero
eax&=ebx;
eax|=3;
ecx^=0x69;
ebx=~ebx;
shl/sal eax, 8
eax<<=8;
shr
eax, 6
eax>>=6;
sar
ecx, 7
replicate sign bit
rol
esi, 11
esi=(esi>>21)|(esi<<11)
ror
esi, 21
esi=(esi>>21)|(esi<<11)
rcl, rcr rotate through CF
shl
eax, cl
eax<<=cl;
Being Effective
lea
eax, MyPtr
(mov
eax, OFFSET MyPtr)
lea
edi, [ebx+edi]
lea
eax, [esp+10]
lea
ecx, [eax*2+eax+6]
lea
eax, MyPtr[eax+4][esi*2]
[base[*scale]][+displacement][+index]
Sizing Things Up
movzx/movsx eax, bh
mov
ax, WORD PTR [MyPtr+6]
inc
BYTE PTR [eax]
cbw
(al->ax)
cwd,cwde
(ax->dx:ax, ax->eax)
cdq
(eax->edx:eax)
Flags
Getting Around
Unconditional:
JMP dest
Conditional (165) :
JCXZ, JECXZ, LOOP
JC/JB/JNAE, JNC/JNB/JAE, JBE/JNA, JA/JNBE
JE/JZ, JNE/JNZ, JS, JNS
JL/JNGE, JGE/JNL, JLE/JNG, JG/JNLE
JO, JNO, JP/JPE, JNP/JPO
Interrupts:
int 2Eh
into
Addressing Modes
Stacking Up
esp, ebp, ss are used to reference the stack
esp points to the top of the stack (last pushed value), while
ebp points to whatever you want, but usually the frame
pointer
The stack grows downwards in memory
The call instruction automatically pushes the return address
ret alone pops the return address and jumps to it
ret with an immediate operand also pops X bytes of
arguments
Calling Conventions
Today, arguments are almost universally pushed last-argument-first;
this accommodates varargs. (If you remember Windows 3.1, the
PASCAL calling convention was first-argument-pushed-first.)
Return values are in eax for most data types
_stdcall and _thiscall (except with varargs) let the called function
clean up the stack at the end of a call
_cdecl lets the caller clean up the stack after a function call returns
_fastcall is something thats used to mimic the speed of pure assembly
programs, and therefore is generally irrelevant to real assembly
programs. I dont have any details on it.
All calling conventions engage in some degree of name-mangling
when going from source code to object code.
Typical prologue:
push ebp
mov ebp,esp
sub esp,LOCALSIZE
Typical epilogue:
pop ebp
ret
<or> ret x, where x is an immediate specifying bytes to pop
In MS VC++, you can tell the compiler to omit prologue and epilogue code
(almost always because you want to write it yourself in assembly) by
specifying the attribute _declspec(_naked)
Generally, temporary registers are saved and restored in these areas too
If you omit the frame pointer, a lot of this goes away
SEH adds a bunch of additional lines, but Im still researching it.
String Instructions
Prefixes
lock is useful for multiprocessor systems, but will not be
discussed here.
rep* is generally used with string instructions, to repeat an
instruction a maximum of ecx times
rep is unconditional
repe/repz and repnz/repne are conditional, based, of course,
on the zero flag
stos*, movs*, ins*, and outs* can use unconditional repeats
scas* and cmps* can use conditional repeats
AAD
CLC
DAA
IN
JC
JNA
JNGE
JPE
LES
LOOPZ
OR
REP
SAHF
STC
XLAT
AAM
CLD
DAS
INC
JCXZ
JNAE
JNL
JPO
LOCK
MOV
OUT
REPE
SAL
STD
XOR
AAS
CLI
DEC
INT
JE
JNB
JNLE
JS
LODSB
MOVSB
POP
REPNE
SAR
STOSB
ADC
CMC
DIV
INTO
JG
JNBE
JNO
JZ
LODSW
MOVSW
POPF
REPNZ
SBB
STOSW
ADD
CMP
ESC
IRET
JGE
JNC
JNP
LAHF
LOOP
MUL
PUSH
REPZ
SCASB
SUB
AND
CMPSB
HLT
JA
JL
JNE
JNS
LDS
LOOPE
NEG
PUSHF
RET
SCASW
TEST
CALL
CMPSW
IDIV
JAE
JNZ
LOOPNE
NOP
RCL
ROL
SHL
WAIT
INS
PUSHA
INSB
INSW
LEAVE
OUTS
OUTSB
LAR
SIDT
LGDT
SLDT
LIDT
SMSW
LLDT
STR
LMSW
VERR
LSL
VERW
80286:
ARPL
LTR
CLTS
SGDT
BSR
INSD
MOVZX
SETAE
SETLE
SETNGE
SETP
BT
JECXZ
OUTSD
SETB
SETNA
SETNL
SETPE
BTC
LFS
POPAD
SETBE
SETNAE
SETNLE
SETPO
BTR
LGS
POPFD
SETC
SETNB
SETNO
SETS
BTS
LODSD
PUSHAD
SETE
SETNBE
SETNP
SETZ
CDQ
LSS
PUSHFD
SETG
SETNC
SETNS
SHLD
CMPSD
MOVSD
SCASD
SETGE
SETNE
SETNZ
SHRD
CMPXCHG
INVD
RDMSR
RDTSC
Pentium I:
CMPXCHG8B
CPUID
RSM
WRMSR
Other Stuff:
CLFLUSH
CMOV* CR0
CR2
CR3
CR4
DR0-7
LMXCSR LFENCE MFENCE PAUSE PREFETCH*
STMXCSR
SYSENTER
SYSEXIT UD2
SFENCE
Floating-point instructions
Vector instructions
Standalone assembly file directives?
Structured exception handling?
Disassembly techniques?