A.exe

advertisement
Principles of Computers
th
17 Lecture
http://d3s.mff.cuni.cz/~jezek
Pavel Ježek, Ph.D.
pavel.jezek@d3s.mff.cuni.cz
CHARLES UNIVERSITY IN PRAGUE
faculty of mathematics and physics
Selected Faults/Traps/Exceptions of x86 ISA
CPU Exception
Interrupt vector
(all push IP of faulting instruction)
Invalid opcode
6
Divide by zero (DIV0)
0
Alignment check
17 ($11)
General Protection Fault
13 ($0D)
Page Fault
14 ($0E)
kernel init
call Exec(‘shell.exe’)
load shell.exe
call shell.exe entrypoint
...
repeat
...
until key <> ENTER
call Exec(‘P.EXE’)
load P.EXE
load & relocate EXE image
...
...
...
...
call P.EXE entrypoint
...
... main program of P.EXE
...
kernel init
call Exec(‘shell.exe’)
load shell.exe
call shell.exe entrypoint
...
repeat
...
until key <> ENTER
call Exec(‘P.EXE’)
load P.EXE
load & relocate EXE image
load & relocate DLL images (A.DLL, B.DLL)
...
...
call A.DLL entrypoint
call B.DLL entrypoint
call P.EXE entrypoint
...
... main program of P.EXE
...
Dependency Walker (depends.exe)
Process Explorer
www.sysinternals.com
Really Dynamic DLL Loading Example
...
A’s entrypoint
Non-present
Kernel/Supervisor
User Read/Only
User Read/Write
...
...
...
9
8
7
6
5
4
3
2
1
PT
IVT
kernel proc table
data
...
page tbl
kernel code
kernel code
stack
stack
guard page
free
free
free
free
free
free
free
free
free
free
free
A data
A data
A data
A code
A code
→ read variable at address 8200
A code
(= in page 8 for 1kB pages)
A code
→ call procedure at address 4000
A code
(= in page 3 for 1kB pages)
...
...
A’s entrypoint
Non-present
Kernel/Supervisor
User Read/Only
User Read/Write
...
...
...
9
8
7
6
5
4
3
2
1
PT
IVT
kernel proc table
data
...
page tbl
kernel code
kernel code
stack
stack
guard page
free
free
free
free
free
free
free
free
free
free
free
A data (guard)
A data (guard)
A data (guard)
A code (guard)
A code (guard)
A code (guard)
A code (guard)
A code
...
...
A’s entrypoint
Non-present
Kernel/Supervisor
User Read/Only
User Read/Write
...
...
...
9
8
7
6
5
4
3
2
1
PT
IVT
kernel proc table
data
...
page tbl
kernel code
kernel code
stack
stack
guard page
free
free
free
free
free
free
free
free
free
free
free
A data (guard)
A data (guard)
A data (guard)
A code (guard)
A code (guard)
A code (guard)
page fault
A code (guard)
→ call procedure at address 4000
A code
(= in page 3 for 1kB pages)
...
...
A’s entrypoint
Non-present
Kernel/Supervisor
User Read/Only
User Read/Write
...
...
...
9
8
7
6
5
4
3
2
1
PT
IVT
kernel proc table
data
...
page tbl
kernel code
kernel code
stack
stack
guard page
free
free
free
free
free
free
free
free
free
free
free
A data (guard)
A data (guard)
A data (guard)
A code (guard)
A code (guard)
A code
A code (guard)
→ call procedure at address 4000
A code
(= in page 3 for 1kB pages)
...
...
A’s entrypoint
Non-present
Kernel/Supervisor
User Read/Only
User Read/Write
...
...
...
9
8
7
6
5
4
3
2
1
PT
IVT
kernel proc table
data
...
page tbl
kernel code
kernel code
stack
stack
guard page
free
free
free
free
free
free
free
free
free
free
free
A data (guard)
page fault
A data (guard)
A data (guard)
A code (guard)
A code (guard)
→ read variable at address 8200
A code
(= in page 8 for 1kB pages)
A code (guard)
→ call procedure at address 4000
A code
(= in page 3 for 1kB pages)
...
...
A’s entrypoint
Non-present
Kernel/Supervisor
User Read/Only
User Read/Write
...
...
...
9
8
7
6
5
4
3
2
1
PT
IVT
kernel proc table
data
...
page tbl
kernel code
kernel code
stack
stack
guard page
free
free
free
free
free
free
free
free
free
free
free
A data
page fault
A data (guard)
A data (guard)
A code (guard)
A code (guard)
→ read variable at address 8200
A code
(= in page 8 for 1kB pages)
A code (guard)
→ call procedure at address 4000
A code
(= in page 3 for 1kB pages)
...
kernel init
call Exec(‘shell.exe’)
load shell.exe
call shell.exe entrypoint
...
repeat
...
until key <> ENTER
call Exec(‘P.EXE’)
load P.EXE
load & relocate EXE image
load & relocate DLL images (A.DLL, B.DLL)
...
...
call A.DLL entrypoint
call B.DLL entrypoint
call P.EXE entrypoint
...
... main program of P.EXE
...
kernel init
call Exec(‘shell.exe’)
load shell.exe
call shell.exe entrypoint
...
repeat
...
until key <> ENTER
call Exec(‘P.EXE’)
load P.EXE
load & relocate EXE image
load & relocate DLL images (A.DLL, B.DLL)
...
...
call A.DLL entrypoint
call B.DLL entrypoint
call P.EXE entrypoint
...
...
call Exit
clean up (release resources)
...
...
... (never here = rest of P.EXE main program) ...
...
ret
goto
kernel init
call Exec(‘shell.exe’)
load shell.exe
call shell.exe entrypoint
...
repeat
...
until key <> ENTER
call Exec(‘P.EXE’)
load P.EXE
load & relocate EXE image
load & relocate DLL images (A.DLL, B.DLL)
...
...
call A.DLL entrypoint
call B.DLL entrypoint
call P.EXE entrypoint
...
...
call Exit
clean up (release resources)
...
IP ret
... should not get here ...
...
ret
goto
SP →
...
...
shell’s entrypoint
arguments
return address
shell → kernelInit
Exec syscall
arguments
return address
Exec → shell
P.EXE’s entrypoint
arguments
return address
P main → Exec
Exit syscall
arguments
return address
Exit → P main
...
...
...
...
...
...
...
...
kernel init
call Exec(‘shell.exe’)
load shell.exe
call shell.exe entrypoint
...
repeat
...
until key <> ENTER
call Exec(‘P.EXE’)
load P.EXE
load & relocate EXE image
load & relocate DLL images (A.DLL, B.DLL)
...
...
call A.DLL entrypoint
call B.DLL entrypoint
call P.EXE entrypoint
...
...
call Exit
clean up (release resources)
...
ret
IP ... P.EXE’s main program continues ...
...
ret
goto
SP →
...
...
shell’s entrypoint
arguments
return address
shell → kernelInit
Exec syscall
arguments
return address
Exec → shell
P.EXE’s entrypoint
arguments
return address
P main → Exec
Exit syscall
arguments
return address
Exit → P main
...
...
...
...
...
...
...
...
kernel init
call Exec(‘shell.exe’)
load shell.exe
call shell.exe entrypoint
...
repeat
...
until key <> ENTER
call Exec(‘P.EXE’)
load P.EXE
load & relocate EXE image
load & relocate DLL images
...
...
call A.DLL entrypoint
call B.DLL entrypoint
call P.EXE entrypoint
...
...
call Exit
clean up (release resources)
IP SP := SP + sizeof(Exit stack frame)
ret
... (never here = rest of P.EXE main program) ...
...
ret
goto
SP →
...
...
shell’s entrypoint
arguments
return address
shell → kernelInit
Exec syscall
arguments
return address
Exec → shell
P.EXE’s entrypoint
arguments
return address
P main → Exec
Exit syscall
arguments
return address
Exit → P main
...
...
...
...
...
...
...
...
kernel init
call Exec(‘shell.exe’)
load shell.exe
call shell.exe entrypoint
...
repeat
...
until key <> ENTER
call Exec(‘P.EXE’)
load P.EXE
load & relocate EXE image
load & relocate DLL images
...
...
call A.DLL entrypoint
call B.DLL entrypoint
call P.EXE entrypoint
...
...
call Exit
clean up (release resources)
SP := SP + sizeof(Exit stack frame)
IP ret
... (never here = rest of P.EXE main program) ...
...
ret
goto
SP →
...
...
shell’s entrypoint
arguments
return address
shell → kernelInit
Exec syscall
arguments
return address
Exec → shell
P.EXE’s entrypoint
arguments
return address
P main → Exec
Exit syscall
arguments
return address
Exit → P main
...
...
...
...
...
...
...
...
kernel init
call Exec(‘shell.exe’)
load shell.exe
call shell.exe entrypoint
...
repeat
...
until key <> ENTER
call Exec(‘P.EXE’)
load P.EXE
load & relocate EXE image
load & relocate DLL images
...
...
call A.DLL entrypoint
call B.DLL entrypoint
call P.EXE entrypoint
...
...
call Exit
clean up (release resources)
SP := SP + sizeof(Exit stack frame)
ret
... (never here = rest of P.EXE main program) ...
IP ...
ret
goto
SP →
...
...
shell’s entrypoint
arguments
return address
shell → kernelInit
Exec syscall
arguments
return address
Exec → shell
P.EXE’s entrypoint
arguments
return address
P main → Exec
Exit syscall
arguments
return address
Exit → P main
...
...
...
...
...
...
...
...
kernel init
call Exec(‘shell.exe’)
load shell.exe
call shell.exe entrypoint
...
repeat
...
until key <> ENTER
call Exec(‘P.EXE’)
load P.EXE
load & relocate EXE image
load & relocate DLL images
push currentPID
currentPID := AllocateNewPID;
context switch
call A.DLL entrypoint
call B.DLL entrypoint
call P.EXE entrypoint
...
...
call Exit
clean up (release resources)
SP := SP + sizeof(Exit stack frame)
ret
... (never here = rest of P.EXE main program) ...
pop currentPID context switch
ret
goto
1) Allocated memory (pages)
kernel init
call Exec(‘shell.exe’)
load shell.exe
call shell.exe entrypoint
... AllocMem → for currentPID = 1
repeat
...
until key <> ENTER
call Exec(‘P.EXE’)
load P.EXE
load & relocate EXE image
load & relocate DLL images
push currentPID (1)
currentPID := AllocateNewPID; (2)
context switch to PID 2
call A.DLL entrypoint
call B.DLL entrypoint
call P.EXE entrypoint
...
... AllocMem → for currentPID = 2
call Exit
clean up (release resources)
SP := SP + sizeof(Exit stack frame)
ret
... (never here = rest of P.EXE main program) ...
pop currentPID (1) context switch back to PID 1
ret
goto
1) Allocated memory (pages)
2) CPU fault → kernel interrupt handler →
call procTable[currentPID].faultHandlers[faultID]
kernel init
call Exec(‘shell.exe’)
load shell.exe
call shell.exe entrypoint
... AllocMem → for currentPID = 1
repeat
...
until key <> ENTER
call Exec(‘P.EXE’)
load P.EXE
load & relocate EXE image
load & relocate DLL images
push currentPID (1)
currentPID := AllocateNewPID; (2)
context switch to PID 2
call A.DLL entrypoint
call B.DLL entrypoint
call P.EXE entrypoint
...
... AllocMem → for currentPID = 2
call Exit
clean up (release resources)
SP := SP + sizeof(Exit stack frame)
ret
... (never here = rest of P.EXE main program) ...
pop currentPID (1) context switch back to PID 1
ret
goto
1) Allocated memory (pages)
2) CPU fault → kernel interrupt handler →
call procTable[currentPID].faultHandlers[faultID]
3) Open files – e.g. ReadFile(fileDesc, ...):
read from procTable[currentPID].fileDescTable[fileDesc]
kernel init
call Exec(‘shell.exe’)
load shell.exe
call shell.exe entrypoint
... AllocMem → for currentPID = 1
repeat
...
until key <> ENTER
call Exec(‘P.EXE’)
load P.EXE
load & relocate EXE image
load & relocate DLL images
push currentPID (1)
currentPID := AllocateNewPID; (2)
context switch to PID 2
call A.DLL entrypoint
call B.DLL entrypoint
call P.EXE entrypoint
...
... AllocMem → for currentPID = 2
call Exit
clean up (release resources)
SP := SP + sizeof(Exit stack frame)
ret
... (never here = rest of P.EXE main program) ...
pop currentPID (1) context switch back to PID 1
ret
goto
kernel init
call Exec(‘shell.exe’)
load shell.exe
call shell.exe entrypoint
... AllocMem → for currentPID = 1
repeat
...
until key <> ENTER
call Exec(‘P.EXE’)
load P.EXE
load & relocate EXE image
load & relocate DLL images
push currentPID (1)
currentPID := AllocateNewPID; (2)
1) Allocated memory (pages)
2) CPU fault → kernel interrupt handler →
call procTable[currentPID].faultHandlers[faultID]
3) Open files – e.g. ReadFile(fileDesc, ...):
read from procTable[currentPID].fileDescTable[fileDesc]
4) Current path – e.g. OpenFile(path, ...)
if path startsWith ‘/’ or ‘\’ then
open file at (path)
else
open file at (procTable[currentPID].workingDir + path)
context switch to PID 2
call A.DLL entrypoint
call B.DLL entrypoint
call P.EXE entrypoint
...
... AllocMem → for currentPID = 2
call Exit
clean up (release resources)
SP := SP + sizeof(Exit stack frame)
ret
... (never here = rest of P.EXE main program) ...
pop currentPID (1) context switch back to PID 1
ret
goto
kernel init
call Exec(‘shell.exe’)
load shell.exe
call shell.exe entrypoint
... AllocMem → for currentPID = 1
repeat
...
until key <> ENTER
call Exec(‘P.EXE’)
load P.EXE
load & relocate EXE image
load & relocate DLL images
push currentPID (1)
currentPID := AllocateNewPID; (2)
1) Allocated memory (pages)
2) CPU fault → kernel interrupt handler →
call procTable[currentPID].faultHandlers[faultID]
3) Open files – e.g. ReadFile(fileDesc, ...):
read from procTable[currentPID].fileDescTable[fileDesc]
4) Current path – e.g. OpenFile(path, ...)
if path startsWith ‘/’ or ‘\’ then
open file at (path)
else
open file at (procTable[currentPID].workingDir + path)
5) List of loaded DLLs
context switch to PID 2
call A.DLL entrypoint
call B.DLL entrypoint
call P.EXE entrypoint
...
... AllocMem → for currentPID = 2
call Exit
clean up (release resources)
SP := SP + sizeof(Exit stack frame)
ret
... (never here = rest of P.EXE main program) ...
pop currentPID (1) context switch back to PID 1
ret
goto
Further Options How to Take Advantage of Processes …
kernel init
call Exec(‘shell.exe’)
load shell.exe
call shell.exe entrypoint
...
repeat
...
until key <> ENTER
call Exec(‘P.EXE’)
load P.EXE
load & relocate EXE image
load & relocate DLL images
push currentPID
currentPID := AllocateNewPID;
call A.DLL entrypoint
call B.DLL entrypoint
call P.EXE entrypoint
...
...
call Exit
clean up (release resources)
SP := SP + sizeof(Exit stack frame)
ret
... (never here = rest of P.EXE main program) ...
pop currentPID
ret
goto
SP →
???
SP →
SP →
...
...
shell’s entrypoint
arguments
return address
shell → kernelInit
shell local & temporary
variables
Exec syscall
arguments
return address
Exec → shell
Exec local & temporary
variables
P.EXE’s entrypoint
arguments
return address
P main → Exec
P main local & temporary
variables
Exit syscall
arguments
return address
Exit → P main
Exit local & temporary
variables
...
...
...
...
...
...
...
...
kernel init
call Exec(‘shell.exe’)
load shell.exe
call shell.exe entrypoint
...
repeat
...
until key <> ENTER
call Exec(‘P.EXE’)
load P.EXE
load & relocate EXE image
load & relocate DLL images
push currentPID
currentPID := AllocateNewPID;
call A.DLL entrypoint
call B.DLL entrypoint
call P.EXE entrypoint
...
call f1 in P.EXE
...
call f2 in P.EXE
...
call Exit
clean up (release resources)
IP
SP := SP + sizeof(Exit stack frame)
ret
... (never here = rest of f2) ...
... (never here = rest of f1) ...
pop currentPID
ret
goto
SP →
...
...
shell’s entrypoint
arguments
return address
shell → kernelInit
Exec syscall
arguments
return address
Exec → shell
P.EXE’s entrypoint
arguments
return address
P main → Exec
f1 in P.EXE function
arguments
return address
f1 → P main
f2 in P.EXE function
arguments
return address
f2 → f1
Exit syscall
arguments
return address
Exit → f2
...
...
...
...
kernel init
call Exec(‘shell.exe’)
load shell.exe
call shell.exe entrypoint
...
repeat
...
until key <> ENTER
call Exec(‘P.EXE’)
load P.EXE
load & relocate EXE image
load & relocate DLL images
push currentPID
currentPID := AllocateNewPID;
call A.DLL entrypoint
call B.DLL entrypoint
call P.EXE entrypoint
...
call f1 in P.EXE
...
call f2 in P.EXE
...
call Exit
clean up (release resources)
SP := SP + sizeof(Exit stack frame)
ret
IP
... (never here = rest of f2) ...
... (never here = rest of f1) ...
pop currentPID
ret
goto
SP →
...
...
shell’s entrypoint
arguments
return address
shell → kernelInit
Exec syscall
arguments
return address
Exec → shell
P.EXE’s entrypoint
arguments
return address
P main → Exec
f1 in P.EXE function
arguments
return address
f1 → P main
f2 in P.EXE function
arguments
return address
f2 → f1
Exit syscall
arguments
return address
Exit → f2
...
...
...
...
kernel init
call Exec(‘shell.exe’)
load shell.exe
call shell.exe entrypoint
...
repeat
...
until key <> ENTER
call Exec(‘P.EXE’)
load P.EXE
load & relocate EXE image
load & relocate DLL images
push currentPID
currentPID := AllocateNewPID;
call A.DLL entrypoint
call B.DLL entrypoint
call P.EXE entrypoint
...
call f1 in P.EXE
...
call f2 in P.EXE
...
call Exit
clean up (release resources)
SP := SP + sizeof(Exit stack frame)
ret
... (never here = rest of f2) ...
IP
f1 execution continues ...
pop currentPID
ret
goto
SP →
...
...
shell’s entrypoint
arguments
return address
shell → kernelInit
Exec syscall
arguments
return address
Exec → shell
P.EXE’s entrypoint
arguments
return address
P main → Exec
f1 in P.EXE function
arguments
return address
f1 → P main
f2 in P.EXE function
arguments
return address
f2 → f1
Exit syscall
arguments
return address
Exit → f2
...
...
...
...
kernel init
call Exec(‘shell.exe’)
load shell.exe
call shell.exe entrypoint
...
repeat
...
until key <> ENTER
call Exec(‘P.EXE’)
load P.EXE
load & relocate EXE image
load & relocate DLL images
push currentPID
currentPID := AllocateNewPID;
procTable[currentPID].oldSP := SP
call A.DLL entrypoint
call B.DLL entrypoint
call P.EXE entrypoint
...
call f1 in P.EXE
...
call f2 in P.EXE
...
call Exit
clean up (release resources)
SP := procTable[currentPID].oldSP
IP
ret
... (never here = rest of f2) ...
... (never here = rest of f1) ...
pop currentPID
ret
goto
SP →
...
...
shell’s entrypoint
arguments
return address
shell → kernelInit
Exec syscall
arguments
return address
Exec → shell
P.EXE’s entrypoint
arguments
return address
P main → Exec
f1 in P.EXE function
arguments
return address
f1 → P main
f2 in P.EXE function
arguments
return address
f2 → f1
Exit syscall
arguments
return address
Exit → f2
...
...
...
...
kernel init
call Exec(‘shell.exe’)
load shell.exe
call shell.exe entrypoint
...
repeat
...
until key <> ENTER
call Exec(‘P.EXE’)
load P.EXE
load & relocate EXE image
load & relocate DLL images
push currentPID
currentPID := AllocateNewPID;
procTable[currentPID].oldSP := SP
call A.DLL entrypoint
call B.DLL entrypoint
call P.EXE entrypoint
...
call f1 in P.EXE
...
call f2 in P.EXE
...
call Exit
clean up (release resources)
SP := procTable[currentPID].oldSP
ret
IP
... (never here = rest of f2) ...
... (never here = rest of f1) ...
pop currentPID
ret
goto
SP →
...
...
shell’s entrypoint
arguments
return address
shell → kernelInit
Exec syscall
arguments
return address
Exec → shell
P.EXE’s entrypoint
arguments
return address
P main → Exec
f1 in P.EXE function
arguments
return address
f1 → P main
f2 in P.EXE function
arguments
return address
f2 → f1
Exit syscall
arguments
return address
Exit → f2
...
...
...
...
kernel init
call Exec(‘shell.exe’)
load shell.exe
call shell.exe entrypoint
...
repeat
...
until key <> ENTER
call Exec(‘P.EXE’)
load P.EXE
load & relocate EXE image
load & relocate DLL images
push currentPID
currentPID := AllocateNewPID;
procTable[currentPID].oldSP := SP – sizeof(entrypoint’s stack frame)
call A.DLL entrypoint
call B.DLL entrypoint
call P.EXE entrypoint
...
call f1 in P.EXE
...
call f2 in P.EXE
...
call Exit
SP →
clean up (release resources)
SP := procTable[currentPID].oldSP
IP
ret
... (never here = rest of f2) ...
... (never here = rest of f1) ...
pop currentPID
ret
goto
...
...
shell’s entrypoint
arguments
return address
shell → kernelInit
Exec syscall
arguments
return address
Exec → shell
P.EXE’s entrypoint
arguments
return address
P main → Exec
f1 in P.EXE function
arguments
return address
f1 → P main
f2 in P.EXE function
arguments
return address
f2 → f1
Exit syscall
arguments
return address
Exit → f2
...
...
...
...
kernel init
call Exec(‘shell.exe’)
load shell.exe
call shell.exe entrypoint
...
repeat
...
until key <> ENTER
call Exec(‘P.EXE’)
load P.EXE
load & relocate EXE image
load & relocate DLL images
SP →
push currentPID
currentPID := AllocateNewPID;
procTable[currentPID].oldSP := SP – sizeof(entrypoint’s stack frame)
call A.DLL entrypoint
call B.DLL entrypoint
call P.EXE entrypoint
...
call f1 in P.EXE
...
call f2 in P.EXE
...
call Exit
clean up (release resources)
SP := procTable[currentPID].oldSP
ret
IP
... (never here = rest of f2) ...
... (never here = rest of f1) ...
pop currentPID
ret
goto
...
...
shell’s entrypoint
arguments
return address
shell → kernelInit
Exec syscall
arguments
return address
Exec → shell
P.EXE’s entrypoint
arguments
return address
P main → Exec
f1 in P.EXE function
arguments
return address
f1 → P main
f2 in P.EXE function
arguments
return address
f2 → f1
Exit syscall
arguments
return address
Exit → f2
...
...
...
...
...
Non-present
Kernel/Supervisor
User Read/Only
User Read/Write
PT
IVT
kernel proc table
data
...
page tbl
kernel code
kernel code
stack
stack
guard page
free
free
free
free
free
free
free
free
free
free
free
free
free
free
free
free
free
A data
A code
...
...
Non-present
Kernel/Supervisor
User Read/Only
User Read/Write
PT
IVT
kernel proc table
data
...
page tbl
kernel code
kernel code
stack
stack
guard page
free
free
free
free
free
free
free
free
free
free
free
free
free
free
free
free
A heap
A data
A code
→ Pascal runtime’s call of syscall (OS API) AllocMem
...
...
Non-present
Kernel/Supervisor
User Read/Only
User Read/Write
PT
IVT
kernel proc table
data
...
page tbl
kernel code
kernel code
stack
stack
guard page
free
free
free
free
free
free
free
free
free
free
free
free
free
free
A heap
A heap
A heap
A data
A code
...
...
Non-present
Kernel/Supervisor
User Read/Only
User Read/Write
PT
IVT
kernel proc table
data
...
page tbl
kernel code
kernel code
stack
stack
guard page
free
free
free
free
free
free
free
free
free
free
B heap
B data
B code
B code
A heap
A heap
A heap
A data
A code
...
...
Non-present
Kernel/Supervisor
User Read/Only
User Read/Write
PT
IVT
kernel proc table
data
...
page tbl
kernel code
kernel code
stack
stack
guard page
free
free
free
free
free
free
free
free
free
free
B heap
B data
B code
B code
A heap
A heap
A heap
A data
A code
...
...
Non-present
Kernel/Supervisor
User Read/Only
User Read/Write
A PT
...
kernel proc table
data B page tbl
A page tbl
kernel code
kernel code
stack
stack
guard page
free
free
free
free
free
free
free
free
free
free
B heap
B data
B code
B code
A heap
A heap
A heap
A data
A code
...
B PT
CPU (x86/IA-32)
EIP
31
0
ESP
31
0
CR3
31 page table base 0
...
Non-present
Kernel/Supervisor
User Read/Only
User Read/Write
A PT
...
kernel proc table
data B page tbl
A page tbl
kernel code
kernel code
stack
stack
guard page
free
free
free
free
free
free
free
free
free
free
B heap
B data
B code
B code
A heap
A heap
A heap
A data
A code
...
B PT
CPU (x86/IA-32)
EIP
31
0
ESP
31
0
CR3
31 page table base 0
...
Non-present
Kernel/Supervisor
User Read/Only
User Read/Write
A PT
...
kernel proc table
data B page tbl
A page tbl
kernel code
kernel code
stack
stack
guard page
free
free
free
free
free
free
free
free
free
free
B heap
B data
B code
B code
A heap
A heap
A heap
A data
A code
...
B PT
CPU (x86/IA-32)
EIP
31
0
ESP
31
0
CR3
31 page table base 0
...
Non-present
Kernel/Supervisor
User Read/Only
User Read/Write
A PT
...
kernel proc table
data B page tbl
A page tbl
kernel code
kernel code
stack
stack
guard page
free
free
free
free
free
free
free
free
free
free
B heap
B data
B code
B code
A heap
A heap
A heap
A data
A code
...
B PT
CPU (x86/IA-32)
EIP
31
0
ESP
31
0
CR3
31 page table base 0
...
Non-present
Kernel/Supervisor
User Read/Only
User Read/Write
A PT
...
kernel proc table
data B page tbl
A page tbl
kernel code
kernel code
stack
stack
guard page
free
free
free
free
free
free
free
free
free
free
B heap
B data
B code
B code
A heap
A heap
A heap
A data
A code
...
B PT
CPU (x86/IA-32)
EIP
31
0
ESP
31
0
CR3
31 page table base 0
1) Allocated memory (pages)
2) CPU fault → kernel interrupt handler
kernel init
call procTable[currentPID].faultHandlers[faultID]
call Exec(‘shell.exe’)
3)
Open files – e.g. ReadFile(fileDesc, ...):
load shell.exe
read from procTable[currentPID].fdt[fileDesc]
call shell.exe entrypoint
4) Current path – e.g. OpenFile(path, ...)
...
if path startsWith ‘/’ or ‘\’ then
repeat
open file at (path)
...
else
until key <> ENTER
open file at (procTable[currentPID].workingDir + path)
call Exec(‘P.EXE’)
5) List of loaded DLLs
load P.EXE
6) Page table (state of the address space)
load & relocate EXE image
load & relocate DLL images
push currentPID
context switch to PID 2
currentPID := AllocateNewPID;
procTable[currentPID].pageTable := InitilizeNewPageTable;
context switch to PID 2
CR3 := procTable[currentPID].pageTable;
procTable[currentPID].oldSP := SP – sizeof(entrypoint’s stack frame)
call A.DLL entrypoint
call B.DLL entrypoint
call P.EXE entrypoint
...
call f1 in P.EXE
...
call f2 in P.EXE
...
call Exit
clean up (release resources)
SP := procTable[currentPID].oldSP
ret
... (never here = rest of f2) ...
... (never here = rest of f1) ...
pop currentPID
context switch back to PID 1
CR3 := procTable[currentPID].pageTable;
ret
goto
...
nil
= address 0
= pointer(0)
Non-present
Kernel/Supervisor
User Read/Only
User Read/Write
A PT
...
kernel proc table
data B page tbl
A page tbl
kernel code
kernel code
stack
stack
guard page
free
free
free
free
free
free
free
free
free
free
B heap
B data
B code
B code
A heap
A heap
A heap
A data
A code
...
B PT
CPU (x86/IA-32)
EIP
31
0
ESP
31
0
CR3
31 page table base 0
...
nil
= address 0
= pointer(0)
Non-present
Kernel/Supervisor
User Read/Only
User Read/Write
A PT
...
kernel proc table
data B page tbl
A page tbl
kernel code
kernel code
stack
stack
guard page
free
free
free
free
free
free
free
free
free
free
B heap
B data
B code
B code
A heap
A heap
A heap
A data
A code
page 0
B PT
CPU (x86/IA-32)
EIP
31
0
ESP
31
0
CR3
31 page table base 0
How a Debugger Works?
Visual Studio 2015 Community
Visual Studio 2015 Enterprise
google: mff dreamspark
code and data of
DEBUGGER
code and data of debugged
application (= debugee)
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
00
6A
00
B9
10
1A
68
00
B9
10
5B
68
40
6A
...
$01000000
$00B9100C
push dword 0
push dword ptr [00B9105Bh]
$00B91007
push dword ptr [00B9105Bh]
$00B91002
$00B91000
push dword 40h
code and data of
DEBUGGER
code and data of debugged
application (= debugee)
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
00
6A
00
B9
10
1A
68
00
B9
10
5B
68
40
6A
...
$01000000
$00B9100C
push dword 0
push dword ptr [00B9105Bh]
$00B91007
push dword ptr [00B9105Bh]
$00B91002
$00B91000
push dword 40h
code and data of
DEBUGGER
code and data of debugged
application (= debugee)
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
00
6A
00
B9
10
1A
68
00
B9
10
5B
68
40
6A
...
$01000000
$00B9100C
push dword 0
push dword ptr [00B9105Bh]
$00B91007
push dword ptr [00B9105Bh]
$00B91002
$00B91000
push dword 40h
code and data of
DEBUGGER
code and data of debugged
application (= debugee)
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
00
6A
00
B9
10
1A
68
00
B9
10
5B
68
40
6A
...
$01000000
$00B9100C
push dword 0
push dword ptr [00B9105Bh]
$00B91007
push dword ptr [00B9105Bh]
$00B91002
$00B91000
push dword 40h
code and data of
DEBUGGER
code and data of debugged
application (= debugee)
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
00
6A
00
B9
10
1A
68
00
B9
10
5B
68
40
6A
...
$01000000
$00B9100C
push dword 0
push dword ptr [00B9105Bh]
$00B91007
push dword ptr [00B9105Bh]
$00B91002
$00B91000
push dword 40h
code and data of
DEBUGGER
code and data of debugged
application (= debugee)
...
...
...
685B10B90068
...
...
...
...
...
...
...
...
... $01000000
...
...
00
6A $00B9100C
00
B9
10
1A
68 $00B91007
00
B9
10
5B
68 $00B91002
40
6A $00B91000
...
variable holding copy of original app’s code
push dword 0
push dword ptr [00B9105Bh]
push dword ptr [00B9105Bh]
push dword 40h
code and data of
DEBUGGER
code and data of debugged
application (= debugee)
JMP to entrypoint
...
...
...
685B10B90068
... $0100FFF0
...
...
...
...
...
...
...
... $01000000
...
...
00
6A $00B9100C
00
B9
10
1A
01 $00B91007
00
FF
F0
15
FF $00B91002
40
6A $00B91000
...
variable holding copy of original app’s code
variable address of debugger step function
push dword 0
push dword ptr [00B9105Bh]
call [0100FFF0h]
push dword ptr [00B9105Bh]
push dword 40h
code and data of
DEBUGGER
code and data of debugged
application (= debugee)
JMP to entrypoint
EIP
...
...
...
685B10B90068
... $0100FFF0
...
...
...
...
...
...
...
... $01000000
...
...
00
6A $00B9100C
00
B9
10
1A
01 $00B91007
00
FF
F0
15
FF $00B91002
40
6A $00B91000
...
variable holding copy of original app’s code
variable address of debugger step function
push dword 0
push dword ptr [00B9105Bh]
call [0100FFF0h]
push dword ptr [00B9105Bh]
push dword 40h
code and data of
DEBUGGER
code and data of debugged
application (= debugee)
EIP
JMP to entrypoint
...
...
...
685B10B90068
... $0100FFF0
...
...
...
...
...
...
...
... $01000000
...
...
00
6A $00B9100C
00
B9
10
1A
01 $00B91007
00
FF
F0
15
FF $00B91002
40
6A $00B91000
...
variable holding copy of original app’s code
variable address of debugger step function
push dword 0
push dword ptr [00B9105Bh]
call [0100FFF0h]
push dword ptr [00B9105Bh]
push dword 40h
code and data of
DEBUGGER
EIP
code and data of debugged
application (= debugee)
JMP to entrypoint
...
...
...
685B10B90068
... $0100FFF0
...
...
...
...
...
...
...
... $01000000
...
...
00
6A $00B9100C
00
B9
10
1A
01 $00B91007
00
FF
F0
15
FF $00B91002
40
6A $00B91000
...
variable holding copy of original app’s code
variable address of debugger step function
Execute main debugger loop (Update/Draw
cycle to display UI)
save state of application (e.g. push all registers
to stack)
push dword 0
push dword ptr [00B9105Bh]
call [0100FFF0h]
push dword ptr [00B9105Bh]
push dword 40h
code and data of
DEBUGGER
EIP
code and data of debugged
application (= debugee)
JMP to entrypoint
...
...
...
685B10B90068
... $0100FFF0
...
...
...
...
...
...
...
... $01000000
...
...
00
6A $00B9100C
00
B9
10
1A
01 $00B91007
00
FF
F0
15
FF $00B91002
40
6A $00B91000
...
variable holding copy of original app’s code
variable address of debugger step function
Execute main debugger loop (Update/Draw
cycle to display UI)
save state of application (e.g. push all registers
to stack)
push dword 0
push dword ptr [00B9105Bh]
call [0100FFF0h]
push dword ptr [00B9105Bh]
push dword 40h
code and data of
DEBUGGER
EIP
code and data of debugged
application (= debugee)
JMP to entrypoint
...
...
...
685B10B90068
... $0100FFF0
...
...
...
...
...
...
...
... $01000000
...
...
00
6A $00B9100C
00
B9
10
1A
68 $00B91007
00
B9
10
5B
68 $00B91002
40
6A $00B91000
...
variable holding copy of original app’s code
variable address of debugger step function
Execute main debugger loop (Update/Draw
cycle to display UI)
save state of application (e.g. push all registers
to stack)
push dword 0
push dword ptr [00B9105Bh]
push dword ptr [00B9105Bh]
push dword 40h
code and data of
DEBUGGER
EIP
code and data of debugged
application (= debugee)
JMP to entrypoint
...
...
...
681A10B9006A
... $0100FFF0
...
...
...
...
...
...
...
... $01000000
...
...
00
6A $00B9100C
00
B9
10
1A
68 $00B91007
00
B9
10
5B
68 $00B91002
40
6A $00B91000
...
variable holding copy of original app’s code
variable address of debugger step function
Execute main debugger loop (Update/Draw
cycle to display UI)
save state of application (e.g. push all registers
to stack)
push dword 0
push dword ptr [00B9105Bh]
push dword ptr [00B9105Bh]
push dword 40h
code and data of
DEBUGGER
EIP
code and data of debugged
application (= debugee)
JMP to entrypoint
...
...
...
681A10B9006A
... $0100FFF0
...
...
...
...
...
...
...
... $01000000
...
...
00
01 $00B9100C
00
FF
F0
15
FF $00B91007
00
B9
10
5B
68 $00B91002
40
6A $00B91000
...
variable holding copy of original app’s code
variable address of debugger step function
Execute main debugger loop (Update/Draw
cycle to display UI)
save state of application (e.g. push all registers
to stack)
push dword 0
call [0100FFF0h]
push dword ptr [00B9105Bh]
push dword ptr [00B9105Bh]
push dword 40h
EIP
code and data of
DEBUGGER
code and data of debugged
application (= debugee)
JMP to entrypoint
...
...
...
681A10B9006A
... $0100FFF0
RET
...
...
...
...
...
...
... $01000000
...
...
00
01 $00B9100C
00
FF
F0
15
FF $00B91007
00
B9
10
5B
68 $00B91002
40
6A $00B91000
...
variable holding copy of original app’s code
variable address of debugger step function
restore state of application & jump back
Execute main debugger loop (Update/Draw
cycle to display UI)
save state of application (e.g. push all registers
to stack)
push dword 0
call [0100FFF0h]
push dword ptr [00B9105Bh]
push dword ptr [00B9105Bh]
push dword 40h
EIP
code and data of
DEBUGGER
code and data of debugged
application (= debugee)
JMP to entrypoint
...
...
...
681A10B9006A
... $0100FFF0
RET
...
...
...
...
...
...
... $01000000
...
...
00
01 $00B9100C
00
FF
F0
15
FF $00B91007
00
B9
10
5B
68 $00B91002
40
6A $00B91000
...
variable holding copy of original app’s code
variable address of debugger step function
restore state of application & jump back
Execute main debugger loop (Update/Draw
cycle to display UI)
save state of application (e.g. push all registers
to stack)
push dword 0
call [0100FFF0h]
push dword ptr [00B9105Bh]
push dword ptr [00B9105Bh]
push dword 40h
code and data of
DEBUGGER
code and data of debugged
application (= debugee)
EIP
JMP to entrypoint
...
...
...
681A10B9006A
... $0100FFF0
RET
...
...
...
...
...
...
... $01000000
...
...
00
01 $00B9100C
00
FF
F0
15
FF $00B91007
00
B9
10
5B
68 $00B91002
40
6A $00B91000
...
variable holding copy of original app’s code
variable address of debugger step function
restore state of application & jump back
Execute main debugger loop (Update/Draw
cycle to display UI)
save state of application (e.g. push all registers
to stack)
push dword 0
call [0100FFF0h]
push dword ptr [00B9105Bh]
push dword ptr [00B9105Bh]
push dword 40h
code and data of
DEBUGGER
code and data of debugged
EIP
application (= debugee)
JMP to entrypoint
...
...
...
681A10B9006A
... $0100FFF0
RET
...
...
...
...
...
...
... $01000000
...
...
00
01 $00B9100C
00
FF
F0
15
FF $00B91007
00
B9
10
5B
68 $00B91002
40
6A $00B91000
...
variable holding copy of original app’s code
variable address of debugger step function
restore state of application & jump back
Execute main debugger loop (Update/Draw
cycle to display UI)
save state of application (e.g. push all registers
to stack)
push dword 0
call [0100FFF0h]
push dword ptr [00B9105Bh]
push dword ptr [00B9105Bh]
push dword 40h
code and data of
DEBUGGER
EIP
code and data of debugged
application (= debugee)
JMP to entrypoint
...
...
...
681A10B9006A
... $0100FFF0
RET
...
...
...
...
...
...
... $01000000
...
...
00
01 $00B9100C
00
FF
F0
15
FF $00B91007
00
B9
10
5B
68 $00B91002
40
6A $00B91000
...
variable holding copy of original app’s code
variable address of debugger step function
restore state of application & jump back
Execute main debugger loop (Update/Draw
cycle to display UI)
save state of application (e.g. push all registers
to stack)
push dword 0
call [0100FFF0h]
push dword ptr [00B9105Bh]
push dword ptr [00B9105Bh]
push dword 40h
code and data of
DEBUGGER
EIP
code and data of debugged
application (= debugee)
JMP to entrypoint
...
...
...
681A10B9006A
... $0100FFF0
RET
...
...
...
...
...
...
... $01000000
...
...
00
01 $00B9100C
00
FF
F0
15
FF $00B91007
00
B9
10
5B
68 $00B91002
40
6A $00B91000
...
variable holding copy of original app’s code
variable address of debugger step function
restore state of application & jump back
Execute main debugger loop (Update/Draw
cycle to display UI)
save state of application (e.g. push all registers
to stack)
push dword 0
call [0100FFF0h]
push dword ptr [00B9105Bh]
push dword ptr [00B9105Bh]
push dword 40h
Stepping in Higher Level Programming Language (e.g. Pascal)
A.pas
C1
C2
C3
A.exe
I1
I2
I3
I4
I5
I6
Stepping in Higher Level Programming Language (e.g. Pascal)
A.pas
C1
C2
C3
A.exe
I1
I2
I3
I4
I5
I6
Stepping in Higher Level Programming Language (e.g. Pascal)
A.pas
C1
C2
C3
A.exe
I1
I2
I3
I4
I5
I6
Typical ISA Arithmetic Instructions
MIPS: a := b op c
x86, 6502: a := a op b
6502 Registers (Accumulator Architecture)
A
7
0
X
7
0
Y
7
0
7
0
7
0
S
0000 0001
P
PC
15
0
Load Value Into Register (6502)
LDA #$xx
A := xx
LDA $xxxx
A := ($xxxx)^
Load Value Into Accumulator
LDA #$xx
A := xx
LDA $xxxx
A := ($xxxx)^
LDA $xxxx,X
A := ($xxxx + X)^
LDA $xxxx,Y
A := ($xxxx + Y)^
LDA ($xx,X)
A := (
(^word($00xx + X))^
)^
LDA ($xx),Y
A := (
(^word($00xx))^ + Y
)^
Load Value Into Register
LDA #$xx
A := xx
LDA $xxxx
A := ($xxxx)^
LDA $xxxx,X
A := ($xxxx + X)^
LDA $xxxx,Y
A := ($xxxx + Y)^
LDX imm/addr
X := imm/addr
LDY imm/addr
X := imm/addr
& Store Value From Register
LDA #$xx
A := xx
LDA $xxxx
A := ($xxxx)^
LDA $xxxx,X
A := ($xxxx + X)^
LDA $xxxx,Y
A := ($xxxx + Y)^
LDX imm/addr
X := imm/addr
LDY imm/addr
X := imm/addr
STA $xxxx
($xxxx)^ := A
STA $xxxx,X
($xxxx + X)^ := A
STA $xxxx,Y
($xxxx + Y)^ := A
STX addr
addr := X
STY addr
addr := Y
Move (Transfer) Value Between Registers
LDA #$xx
A := xx
TAX
X := A
LDA $xxxx
A := ($xxxx)^
TXA
A := X
LDA $xxxx,X
A := ($xxxx + X)^
TAY
Y := A
LDA $xxxx,Y
A := ($xxxx + Y)^
TYA
A := Y
LDX imm/addr
X := imm/addr
TSX
X := S
LDY imm/addr
X := imm/addr
TXS
S := X
STA $xxxx
($xxxx)^ := A
STA $xxxx,X
($xxxx + X)^ := A
STA $xxxx,Y
($xxxx + Y)^ := A
STX addr
addr := X
STY addr
addr := Y
Push To Stack & Pop (Pull) From Stack
LDA #$xx
A := xx
TAX
X := A
LDA $xxxx
A := ($xxxx)^
TXA
A := X
LDA $xxxx,X
A := ($xxxx + X)^
TAY
Y := A
LDA $xxxx,Y
A := ($xxxx + Y)^
TYA
A := Y
LDX imm/addr
X := imm/addr
TSX
X := S
LDY imm/addr
X := imm/addr
TXS
S := X
STA $xxxx
($xxxx)^ := A
STA $xxxx,X
($xxxx + X)^ := A
STA $xxxx,Y
($xxxx + Y)^ := A
STX addr
addr := X
STY addr
addr := Y
PHP
push P (flags)
PLP
pop P (flags)
PHA
push A
PLA
pop A
Setting Flags
LDA #$xx
A := xx
LDA $xxxx
A := ($xxxx)^
LDA $xxxx,X
A := ($xxxx + X)^
LDA $xxxx,Y
A := ($xxxx + Y)^
LDX imm/addr
X := imm/addr
LDY imm/addr
X := imm/addr
STA $xxxx
($xxxx)^ := A
STA $xxxx,X
($xxxx + X)^ := A
STA $xxxx,Y
($xxxx + Y)^ := A
STX addr
addr := X
STY addr
addr := Y
TAX
X := A
TXA
A := X
TAY
Y := A
TYA
A := Y
P.Negative := target.7
TSX
X := S
if target = 0 then
P.Zero := 1
else
P.Zero := 0;
TXS
S := X
PHP
push P (flags)
PLP
pop P (flags)
PHA
push A
PLA
pop A
7654 3210
P
N... ..Z.
Setting Flags
LDA #$xx
A := xx
LDA $xxxx
A := ($xxxx)^
LDA $xxxx,X
A := ($xxxx + X)^
LDA $xxxx,Y
A := ($xxxx + Y)^
LDX imm/addr
X := imm/addr
LDY imm/addr
X := imm/addr
STA $xxxx
($xxxx)^ := A
STA $xxxx,X
($xxxx + X)^ := A
STA $xxxx,Y
($xxxx + Y)^ := A
STX addr
addr := X
STY addr
addr := Y
TAX
X := A
TXA
A := X
TAY
Y := A
TYA
A := Y
P.Negative := target.7
TSX
X := S
if target = 0 then
P.Zero := 1
else
P.Zero := 0;
TXS
S := X
PHP
push P (flags)
PLP
pop P (flags)
PHA
push A
PLA
pop A
7654 3210
P
CLC
P.Carry := 0
SEC
P.Carry := 1
N... ..Z.
Bitwise Operations
ORA imm/addr
A := A BitwiseOr imm/addr
P.Negative := A.7
AND imm/addr
A := A BitwiseAnd imm/addr
EOR imm/addr
A := A BitwiseXor imm/addr
if A = 0 then
P.Zero := 1
else
P.Zero := 0;
? NOT
EOR #$FF
ASL A
A := A shl 1
LSR A
A := A shr 1
Oring 16-bit Numbers (e.g. Little Endian)
MSB of A stored at $A001
LSB of A stored at $A000
A15 A14 A13 A12 A11 A10 A9 A8
A7 A6 A5 A4 A3 A2 A1 A0
or
MSB of B stored at $B001
LSB of B stored at $B000
B15 B14 B13 B12 B11 B10 B9 B8
B7 B6 B5 B4 B3 B2 B1 B0
=
MSB of C stored at $C001
LSB of C stored at $C000
C15 C14 C13 C12 C11 C10 C9 C8
C7 C6 C5 C4 C3 C2 C1 C0
Oring 16-bit Numbers (e.g. Little Endian)
MSB of A stored at $A001
LSB of A stored at $A000
A15 A14 A13 A12 A11 A10 A9 A8
A7 A6 A5 A4 A3 A2 A1 A0
or
or
MSB of B stored at $B001
LSB of B stored at $B000
B15 B14 B13 B12 B11 B10 B9 B8
B7 B6 B5 B4 B3 B2 B1 B0
=
=
MSB of C stored at $C001
LSB of C stored at $C000
C15 C14 C13 C12 C11 C10 C9 C8
C7 C6 C5 C4 C3 C2 C1 C0
LDA $A000
ORA $B000
STA $C000
LDA $A001
ORA $B001
STA $C001
Integer Operations
ADC imm/addr
result := A + imm/addr + P.Carry
P.Carry := result.8
A := result.7 … result.0
P.Negative := A.7
if A = 0 then
P.Zero := 1
else
P.Zero := 0;
7654 3210
P
N... ..ZC
Integer Operations (Adding 8-bit Numbers)
ADC imm/addr
result := A + imm/addr + P.Carry
P.Carry := result.8
A := result.7 … result.0
7654 3210
P
N... ..ZC
LSB of A stored at $A000
P.Negative := A.7
if A = 0 then
P.Zero := 1
else
P.Zero := 0;
A7 A6 A5 A4 A3 A2 A1 A0
+
LSB of B stored at $B000
B7 B6 B5 B4 B3 B2 B1 B0
=
LSB of C stored at $C000
=
C8
carry
C7 C6 C5 C4 C3 C2 C1 C0
LDA $A000
CLC
ADC $B000
STA $C000
0
carry
+
Adding 16-bit Numbers (e.g. Little Endian)
MSB of A stored at $A001
LSB of A stored at $A000
A15 A14 A13 A12 A11 A10 A9 A8
A7 A6 A5 A4 A3 A2 A1 A0
+
MSB of B stored at $B001
LSB of B stored at $B000
B15 B14 B13 B12 B11 B10 B9 B8
B7 B6 B5 B4 B3 B2 B1 B0
=
MSB of C stored at $C001
LSB of C stored at $C000
C15 C14 C13 C12 C11 C10 C9 C8
C7 C6 C5 C4 C3 C2 C1 C0
ADC imm/addr
result := A + imm/addr + P.Carry
P.Carry := result.8
A := result.7 … result.0
P.Negative := A.7
if A = 0 then
P.Zero := 1
else
P.Zero := 0;
Adding 16-bit Numbers (e.g. Little Endian)
LSB of A stored at $A000
A7 A6 A5 A4 A3 A2 A1 A0
+
LSB of B stored at $B000
ADC imm/addr
0
carry
+
result := A + imm/addr + P.Carry
P.Carry := result.8
A := result.7 … result.0
P.Negative := A.7
B7 B6 B5 B4 B3 B2 B1 B0
=
LSB of C stored at $C000
=
C8
carry
C7 C6 C5 C4 C3 C2 C1 C0
if A = 0 then
P.Zero := 1
else
P.Zero := 0;
Adding 16-bit Numbers (e.g. Little Endian)
LSB of A stored at $A000
A7 A6 A5 A4 A3 A2 A1 A0
+
LSB of B stored at $B000
LDA $A000
CLC
ADC $B000
STA $C000
ADC imm/addr
0
carry
+
result := A + imm/addr + P.Carry
P.Carry := result.8
A := result.7 … result.0
P.Negative := A.7
B7 B6 B5 B4 B3 B2 B1 B0
=
LSB of C stored at $C000
=
C8
carry
C7 C6 C5 C4 C3 C2 C1 C0
if A = 0 then
P.Zero := 1
else
P.Zero := 0;
Adding 16-bit Numbers (e.g. Little Endian)
LSB of A stored at $A000
A7 A6 A5 A4 A3 A2 A1 A0
+
LSB of B stored at $B000
LDA $A000
CLC
ADC $B000
STA $C000
0
carry
+
result := A + imm/addr + P.Carry
P.Carry := result.8
A := result.7 … result.0
P.Negative := A.7
B7 B6 B5 B4 B3 B2 B1 B0
=
LSB of C stored at $C000
=
C8
MSB of A stored at $A001
ADC imm/addr
carry
+
A15 A14 A13 A12 A11 A10 A9 A8
+
MSB of B stored at $B001
B15 B14 B13 B12 B11 B10 B9 B8
=
MSB of C stored at $C001
=
C16 C15 C14 C13 C12 C11 C10 C9 C8
carry
C7 C6 C5 C4 C3 C2 C1 C0
if A = 0 then
P.Zero := 1
else
P.Zero := 0;
Adding 16-bit Numbers (e.g. Little Endian)
LSB of A stored at $A000
A7 A6 A5 A4 A3 A2 A1 A0
+
LSB of B stored at $B000
LDA $A000
CLC
ADC $B000
STA $C000
0
carry
+
result := A + imm/addr + P.Carry
P.Carry := result.8
A := result.7 … result.0
P.Negative := A.7
B7 B6 B5 B4 B3 B2 B1 B0
=
LSB of C stored at $C000
=
C8
MSB of A stored at $A001
ADC imm/addr
carry
C7 C6 C5 C4 C3 C2 C1 C0
+
A15 A14 A13 A12 A11 A10 A9 A8
+
MSB of B stored at $B001
B15 B14 B13 B12 B11 B10 B9 B8
=
MSB of C stored at $C001
=
C16 C15 C14 C13 C12 C11 C10 C9 C8
carry
LDA $A001
ADC $B001
STA $C001
if A = 0 then
P.Zero := 1
else
P.Zero := 0;
Adding 16-bit Numbers (e.g. Little Endian)
MSB of A stored at $A001
LSB of A stored at $A000
A15 A14 A13 A12 A11 A10 A9 A8
A7 A6 A5 A4 A3 A2 A1 A0
+
MSB of B stored at $B001
LSB of B stored at $B000
B15 B14 B13 B12 B11 B10 B9 B8
B7 B6 B5 B4 B3 B2 B1 B0
=
MSB of C stored at $C001
LSB of C stored at $C000
C15 C14 C13 C12 C11 C10 C9 C8
C7 C6 C5 C4 C3 C2 C1 C0
LDA
CLC
ADC
STA
LDA
ADC
STA
$A000
$B000
$C000
$A001
$B001
$C001
ADC imm/addr
result := A + imm/addr + P.Carry
P.Carry := result.8
A := result.7 … result.0
P.Negative := A.7
if A = 0 then
P.Zero := 1
else
P.Zero := 0;
Integer Operations – Subtraction? Via Two’s Complement
ADC imm/addr
result := A + imm/addr + P.Carry
P.Carry := result.8
A := result.7 … result.0
P.Negative := A.7
if A = 0 then
P.Zero := 1
else
P.Zero := 0;
A := value – A
↓
INC A
NOT A
ADD value
A := value – A
↓
CLC
ADC #1
EOR #$FF
CLC
ADC value
Integer Operations – Subtraction? Subtract with Borrow
ADC imm/addr
result := A + imm/addr + P.Carry
P.Carry := result.8
A := result.7 … result.0
P.Negative := A.7
if A = 0 then
P.Zero := 1
else
P.Zero := 0;
SBC imm/addr
result := A – imm/addr – not(P.Carry)
P.Carry := not(result.7)
A := result.7 … result.0
P.Negative := A.7
if A = 0 then
P.Zero := 1
else
P.Zero := 0;
Other Integer Operations
ADC imm/addr
result := A + imm/addr + P.Carry
P.Carry := result.8
A := result.7 … result.0
P.Negative := A.7
if A = 0 then
P.Zero := 1
else
P.Zero := 0;
SBC imm/addr
result := A – imm/addr – not(P.Carry)
P.Carry := not(result.7)
A := result.7 … result.0
P.Negative := A.7
if A = 0 then
P.Zero := 1
else
P.Zero := 0;
P.Negative := X/Y.7
INX
INY
DEX
DEY
X
Y
X
Y
:=
:=
:=
:=
X
Y
X
Y
+
+
–
-
1
1
1
1
if X/Y = 0 then
P.Zero := 1
else
P.Zero := 0;
Download