What is a calling convention?
generally: rules for subroutine interface structure
specifically
Copyright By Assignmentchef assignmentchef
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 (its 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
ESPEBP+4, EBPM[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
OUTsrc.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)
elses 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 dont 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, its the
INT instruction:
INT 8-bit imm. # (PUSH EIP), EIP table[imm8]
the RTL is actually a little more complicated, as youll 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 dont 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 processors 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 processors 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
OUTsrc.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: assignmentchef QQ: 1823890830 Email: [email protected]
Reviews
There are no reviews yet.