• What is a calling convention?
– generally: rules for subroutine interface structure
– specifically
Copyright By PowCoder代写 加微信 powcoder
• how information is passed into subroutine
• how information is returned to caller
• who owns registers
– often specified by vendor so that different compilers’ code
can work together (it’s a CONVENTION)
• Parameters for subroutines
– pushed onto stack
– from right to left in C
– order can be language-dependent
The Calling Convention (1)
© , ECE391
• Subroutine return values
– EAX for up to 32 bits
– EDX:EAX for up to 64 bits
– floating-point not discussed
• Register ownership
– return values can be clobbered by subroutine: EAX and EDX
– caller-saved: subroutine free to clobber; caller must preserve
– callee-saved: subroutine must preserve value passed in
• stack structure: ESP and EBP
• other registers: EBX, ESI, and EDI
The Calling Convention (2)
© , ECE391
• The call sequence
0. save caller-saved registers (if desired)
1. push arguments onto stack
2. make the call
3. pop arguments off the stack
4. restore caller-saved registers
Stack Frames in x86 (1)
© , ECE391
• The callee sequence (creates the stack frame)
0. save old base pointer and get new one
1. save callee-saved registers (always)
2. make space for local variables
3. do the function body
4. tear down stack frame (locals)
5. restore callee-saved registers
6. load old base pointer
7. return
Stack Frames in x86 (2)
© , ECE391
• Example of caller code (no caller-saved registers
considered)
int func (int A, int B, int C);
func (100, 200, 300);
Stack Frames in x86 (3)
PUSHL $300
PUSHL $200
PUSHL $100
ADDL $12,%ESP
# result in EAX
© , ECE391
• Example of subroutine code and stack frame creation
and teardown
int func (int A, int B, int C)
/* 12 bytes of local variables */
call func (100, 200, 300);
Stack Frames in x86 (4)
© , ECE391
Stack Frames in x86 (4)
(old frame)
stack on entry
to function
stack during
function body
PUSHL %EBP
MOVL %ESP,%EBP
SUBL $12,%ESP
ESP¬EBP+4, EBP¬M[EBP]
© , ECE391
• Earlier assumptions
– some values start in registers (array pointer in EBX, length in ECX)
– could specify output regs (min. age in EDX, max. age in EDI)
As a C function, we could write…
void find_min_max (person* group, long n_people,
min_max* mm)
Subroutine Example Code
char* name
long age
long min
long max
© , ECE391
void find_min_max (person* group, long n_people, min_max* mm)
© 2021 Yih- . Redistribution prohibited.
Subroutine Example Code (cont.)
(no local vars.)
ret. address
Subroutine Example Code (cont.)
(no local vars.)
ret. address
void foo(char *str) {
char buffer[256];
strcpy(buffer, str);
void main() {
char buf[256];
memset(buf, ‘A’, 255);
buf[255] = ‘\x00’;
void foo(char *str) {
char buffer[16];
strcpy(buffer, str);
void main() {
char buf[256];
memset(buf, ‘A’, 255);
buf[255] = ‘\x00’;
void foo(char *str) {
char buffer[16];
strcpy(buffer, str);
void main() {
char buf[256];
memset(buf, ‘A’, 255);
buf[255] = ‘\x00’;
void foo(char *str) {
char buffer[16];
strcpy(buffer, str);
void main() {
char buf[256];
memset(buf, ‘A’, 255);
buf[255] = ‘\x00’;
void foo(char *str) {
char buffer[16];
strcpy(buffer, str);
void main() {
char buf[256];
memset(buf, ‘A’, 255);
buf[255] = ‘\x00’;
void foo(char *str) {
char buffer[16];
strcpy(buffer, str);
void main() {
char buf[256];
memset(buf, ‘A’, 255);
buf[255] = ‘\x00’;
void foo(char *str) {
char buffer[16];
strcpy(buffer, str);
void main() {
char buf[256];
memset(buf, ‘A’, 255);
buf[255] = ‘\x00’;
void foo(char *str) {
char buffer[16];
strcpy(buffer, str);
void main() {
char buf[256];
memset(buf, ‘A’, 255);
buf[255] = ‘\x00’;
void foo(char *str) {
char buffer[16];
strcpy(buffer, str);
void main() {
char buf[256];
memset(buf, ‘A’, 255);
buf[255] = ‘\x00’;
0x41414141
0x41414141
0x41414141
void foo(char *str) {
char buffer[16];
strcpy(buffer, str);
void main() {
char buf[256];
memset(buf, ‘A’, 255);
buf[255] = ‘\x00’;
0x41414141
0x41414141
0x41414141
mov %ebp, %esp
void foo(char *str) {
char buffer[16];
strcpy(buffer, str);
void main() {
char buf[256];
memset(buf, ‘A’, 255);
buf[255] = ‘\x00’;
0x41414141
0x41414141
0x41414141mov %ebp, %esp
Buffer overflow example
void foo(char *str) {
char buffer[16];
strcpy(buffer, str);
void main() {
char buf[256];
memset(buf, ‘A’, 255);
buf[255] = ‘\x00’;
0x41414141
0x41414141
0x41414141
mov %ebp, %esp
void foo(char *str) {
char buffer[16];
strcpy(buffer, str);
void main() {
char buf[256];
memset(buf, ‘A’, 255);
buf[255] = ‘\x00’;
0x41414141
0x41414141
0x41414141
mov %ebp, %esp
%eip = 0x41414141
0x41414141
0x41414141
0x41414141
• How does a processor communicate with devices?
• Two possibilities
– independent I/O — use special instructions
and a separate I/O port address space
– memory-mapped I/O — use loads/stores
and dedicate part of the memory address space to I/O
• x86 originally used only independent I/O
– but when used in PC, needed a good interface to video memory
– solution? put card on the bus, claim memory addresses!
– now uses both, although ports are somewhat deprecated
Device I/O
© , ECE391
• I/O instructions have not evolved since 8086
– 16-bit port space
• byte addressable
• little-endian (looks like memory)
– instructions
IN port, dest.reg
OUT src.reg, port
– the register operands are NOT general-purpose registers
• all data to/from AL, AX, or EAX
• port is either an 8-bit immediate (not 16!) or DX
Device I/O
© , ECE391
• System software serves three purposes
– virtualization
– protection
– abstraction (particularly hiding asynchrony)
• virtualization:
– the illusion of multiple/practically unlimited resources
• protection:
– reduce/eliminate the chance of accidental and/or malicious
destruction of data/results by another program
Role of System Software (1)
• abstraction:
– hide fundamentally asynchronous nature of processor/device
interaction
– provide simpler and more powerful interfaces (integrated
w/protection)
Role of System Software (2)
else’s codeyour code
buf buf buf
neither can cross
protection boundary
• recall that subroutines allow a programmer
to encapsulate common operations
• the operating system
– want to provide an interface including
common operations
– BUT don’t want to re-link programs
– NOR rely on everyone having exactly
the same OS version
System Calls, Interrupts, and Exceptions (1)
• solution
– add a level of indirection!
• with indirection
– to rewrite OS, just change the table
– application code does not change
System Calls, Interrupts, and Exceptions (2)
“handlers”
or “handler
procedures”
• in LC-3, we used the TRAP instruction; in x86, it’s the
INT instruction:
INT 8-bit imm. # (PUSH EIP), EIP ¬ table[imm8]
– the RTL is actually a little more complicated, as you’ll see
later in course
– called a trap (after instruction, or trap door through protection
– also called a system call (for operating system)
System Calls, Interrupts, and Exceptions (3)
• vector tables/jump tables
– i.e., tables of function pointers
– convenient abstraction for many procedure-like activities
• Question:
– What happens if software does something wrong, e.g.,
• accesses a non-existent memory location?
• issues an illegal/undefined instruction? divides by 0?
• What do we do to handle problems?
– state machine that you design for processor may have don’t cares
– state machine that you build will do something (may be unknown)
– so just let it run! (e.g., 6502 did so… and programmers used!)
System Calls, Interrupts, and Exceptions (4)
• a better solution: exceptions!
– processor maps each problem to a vector #
– calls procedure in vector table by #
• Where else might we use vector tables?
• Consider processor interactions with devices
– a disk access takes about 10 milliseconds
– new machines in lab: 10 ms = 32 million cycles
• should processor sit around asking, “Are my data here yet?”
System Calls, Interrupts, and Exceptions (5)
– analogous to posting a letter to a friend in Europe
– and checking your mailbox every minute for a reply
– instead, have your mail carrier ring your doorbell when it arrives
– in a processor, we call that an interrupt
• How can we use a vector table for interrupts?
– each device has a vector #
– call corresponding procedure in vector table when device generates
– uses one table for all three kinds
– called the Interrupt Descriptor Table (IDT)
System Calls, Interrupts, and Exceptions (6)
• How does a processor support interrupts?
• Logically…
N=8 on x86 (and LC-3)
• How should we change a processor’s state machine
to incorporate interrupts?
Processor Support for Interrupts (1)
N which one?
Z. Kalbarczyk ECE391
LC-3 state machine
interrupt support
• x86 allows software to block interrupts with a status
flag (in EFLAGS)
• normal interrupts occur only when the interrupt
enable flag (IF) is set
• some interrupts are too important
– e.g., memory errors, power warnings, etc.
– these are NOT maskable, and use a separate input to
– called non-maskable interrupts (NMI)
Processor Support for Interrupts (2)
8 which (uses data bus)
• as mentioned earlier
– x86 uses a single vector table
– the Interrupt Descriptor Table (IDT)
– hold vectors for interrupts, exceptions, and system calls
• note that this picture is partly OS-specific
– the exception vector numbers are specified by Intel – Why?
• A: generated directly by processor’s state machine
– programmable interrupt controller (PIC) will be discussed later;
• range of vectors generated is programmable, and is shown for
– note that a single entry is used for all system calls in Linux
Interrupt Descriptor Table
Descriptor Table
• How does a processor communicate with devices?
• Two possibilities
– independent I/O — use special instructions
and a separate I/O port address space
– memory-mapped I/O — use loads/stores
and dedicate part of the memory address space to I/O
• x86 originally used only independent I/O
– but when used in PC, needed a good interface to video memory
– solution? put card on the bus, claim memory addresses!
– now uses both, although ports are somewhat deprecated
Device I/O
© , ECE391
• I/O instructions have not evolved since 8086
– 16-bit port space
• byte addressable
• little-endian (looks like memory)
– instructions
IN port, dest.reg
OUT src.reg, port
– the register operands are NOT general-purpose registers
• all data to/from AL, AX, or EAX
• port is either an 8-bit immediate (not 16!) or DX
Device I/O
© , ECE391
程序代写 CS代考 加微信: powcoder QQ: 1823890830 Email: powcoder@163.com