Добавил:
ИВТ (советую зайти в "Несортированное") Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Скачиваний:
0
Добавлен:
23.11.2024
Размер:
527.38 Кб
Скачать

МИЭТ, СПИНТех, КАИ

Подпрограммы

1 / 29

Подпрограммы

Александра Игоревна Кононова

МИЭТ

26 октября 2021 г. актуальную версию можно найти на https://gitlab.com/illinc/arch-cs

Подпрограммы

} GNU/Linux, BSD (кроме Mac OS X), 32

Локальные переменные

} Mac OS X и MS Windows, 32

Совмещение C++ и ассемблера

} GNU/Linux, BSD (кроме Mac OS X), 64

Искажение имён

} Mac OS X, 64

Про платформы

} MS Windows, 64

МИЭТ, СПИНТех, КАИ

Подпрограммы

2 / 29

Вывод чисел (C++)

#include <stdio.h>

const char* fmt = "x = %d, y = %d\n"; int x = +122;

int main()

{

printf(fmt, x, -13); return 0;

}

$ g++ main.cpp $ ./a.out

x = 122, y = -13

Подпрограммы

} GNU/Linux, BSD (кроме Mac OS X), 32

Локальные переменные

} Mac OS X и MS Windows, 32

Совмещение C++ и ассемблера

} GNU/Linux, BSD (кроме Mac OS X), 64

Искажение имён

} Mac OS X, 64

Про платформы

} MS Windows, 64

МИЭТ, СПИНТех, КАИ

Подпрограммы

 

3 / 29

} GNU/Linux, BSD (кроме

Mac OS X), 32

 

 

 

 

cdecl, нет искажения имён

 

 

 

 

 

 

 

 

 

 

 

 

 

.data

 

 

 

 

 

 

 

 

 

 

 

 

 

 

fmt: .string "x = %d, y = %d\n"

 

 

 

 

 

 

 

 

 

 

 

x: .int +122

 

 

 

 

 

 

 

 

 

 

 

 

 

 

.text

 

 

 

 

 

 

 

 

 

 

 

 

 

 

.globl main

 

 

 

 

 

 

 

 

 

 

 

 

 

 

main:

 

 

 

 

 

 

 

 

 

 

 

 

 

 

pushl $-13

 

 

 

 

 

 

 

 

 

 

 

 

 

 

pushl x

 

 

 

 

 

 

 

 

 

 

 

 

 

 

pushl $fmt

printf(fmt, x, -13)

 

 

 

 

call printf

 

 

 

 

 

 

 

 

 

 

 

 

 

 

add $3*4, %esp

 

 

 

 

 

 

 

 

 

 

 

 

 

 

xor %eax, %eax

return 0 из main()

 

 

 

 

ret

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

*вариант: lea fmt, %eax + push %eax

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Подпрограммы

 

} GNU/Linux, BSD (кроме Mac OS X), 32

Локальные переменные

 

} Mac OS X и MS Windows, 32

 

 

 

 

Совмещение C++ и ассемблера

 

} GNU/Linux, BSD (кроме Mac OS X), 64

 

Искажение имён

 

} Mac OS X, 64

 

 

 

 

 

Про платформы

 

} MS Windows, 64

 

 

 

 

МИЭТ, СПИНТех, КАИ

Подпрограммы

4 / 29

} Mac OS X и MS Windows, 32

 

cdecl, префикс-подчёркивание

 

.data

 

 

 

fmt: .string "x = %d, y = %d\n"

 

x: .int +122

 

 

 

.text

 

 

 

.globl _main

 

 

 

_main:

 

 

 

pushl $-13

 

 

 

pushl x

printf(fmt, x, -13)

 

pushl $fmt

 

call _printf

 

 

 

add $3*4, %esp xor %eax, %eax ret

Подпрограммы

} GNU/Linux, BSD (кроме Mac OS X), 32

Локальные переменные

} Mac OS X и MS Windows, 32

Совмещение C++ и ассемблера

} GNU/Linux, BSD (кроме Mac OS X), 64

Искажение имён

} Mac OS X, 64

Про платформы

} MS Windows, 64

МИЭТ, СПИНТех, КАИ

Подпрограммы

 

5 / 29

} GNU/Linux, BSD (кроме

Mac OS X), 64

 

 

 

 

System V amd64 psABI, нет искажения имён

 

 

 

 

.data

 

 

 

 

 

 

 

 

 

 

 

 

 

 

fmt: .string "x = %d, y = %d\n"

 

 

 

 

 

 

 

 

 

 

 

x: .int +122

 

 

 

 

 

 

 

 

 

 

 

 

 

 

.text

 

 

 

 

 

 

 

 

 

 

 

 

 

 

.globl main

 

 

 

 

 

 

 

 

 

 

 

 

 

 

main:

выравнивание sp на 16 после call main

 

 

 

 

sub $8, %rsp

 

 

 

 

lea fmt(%rip), %rdi

 

 

 

 

 

 

 

 

 

 

 

 

 

movslq x(%rip), %rsi

printf(fmt, x, -13)

 

 

 

 

mov $-13, %rdx

 

 

 

 

 

mov $0, %al

 

 

 

 

 

 

 

 

 

 

 

 

 

 

call printf

восстановление sp перед ret из main

 

 

 

 

add $8, %rsp

 

 

 

 

xor %eax, %eax

 

 

 

 

 

 

 

 

 

 

 

 

 

 

ret

 

 

 

 

 

 

 

 

 

 

 

 

 

 

вариант выравнивания/восстановления sp: push %rbp + pop %rbp

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Подпрограммы

 

} GNU/Linux, BSD (кроме Mac OS X), 32

Локальные переменные

 

} Mac OS X и MS Windows, 32

 

 

 

 

Совмещение C++ и ассемблера

 

} GNU/Linux, BSD (кроме Mac OS X), 64

 

Искажение имён

 

} Mac OS X, 64

 

 

 

 

 

Про платформы

 

} MS Windows, 64

 

 

 

 

восстановление sp перед ret из main
printf(fmt, x, -13)

МИЭТ, СПИНТех, КАИ

Подпрограммы

6 / 29

} Mac OS X, 64

System V amd64 psABI, префикс-подчёркивание

.data

fmt: .string "x = %d, y = %d\n" x: .int +122

.text

.globl _main _main:

sub $8, %rsp выравнивание sp на 16 после call main lea fmt(%rip), %rdi

movslq x(%rip), %rsi mov $-13, %rdx

mov $0, %al call _printf add $8, %rsp xor %eax, %eax ret

Подпрограммы

} GNU/Linux, BSD (кроме Mac OS X), 32

Локальные переменные

} Mac OS X и MS Windows, 32

Совмещение C++ и ассемблера

} GNU/Linux, BSD (кроме Mac OS X), 64

Искажение имён

} Mac OS X, 64

Про платформы

} MS Windows, 64

МИЭТ, СПИНТех, КАИ

Подпрограммы

7 / 29

} MS Windows, 64

 

 

 

 

 

 

 

 

 

 

 

 

Соглашение Microsoft 64, нет искажения имён

 

 

 

 

.data

 

 

 

 

 

 

 

 

 

 

 

 

fmt: .string "x = %d, y = %d\n"

 

 

 

 

 

 

 

 

 

x: .int +122

 

 

 

 

 

 

 

 

 

 

 

 

.text

 

 

 

 

 

 

 

 

 

 

 

 

.globl main

 

 

 

 

 

 

 

 

 

 

 

 

main:

выравнивание sp на 16 после call main

 

 

 

 

sub $8, %rsp

 

 

 

 

sub $32, %rsp

 

 

 

 

 

 

 

 

 

 

 

 

lea fmt(%rip), %rcx

 

 

 

 

 

 

 

 

 

 

 

movslq x(%rip), %rdx

printf(fmt, x, -13)

 

 

 

 

mov $-13, %r8

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

call printf

 

 

 

 

 

 

 

 

 

 

 

 

add $32, %rsp

восстановление sp перед ret из main

 

 

 

 

add $8, %rsp

 

 

 

 

xor %eax, %eax

 

 

 

 

 

 

 

 

 

 

 

 

ret

 

 

 

 

 

 

 

 

 

 

 

 

вариант выравнивания/восстановления sp: push %rbp + pop %rbp

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Подпрограммы

 

} GNU/Linux, BSD (кроме Mac OS X), 32

Локальные переменные

 

} Mac OS X и MS Windows, 32

 

 

 

 

Совмещение C++ и ассемблера

 

} GNU/Linux, BSD (кроме Mac OS X), 64

 

Искажение имён

 

} Mac OS X, 64

 

 

 

 

 

Про платформы

 

} MS Windows, 64

 

 

 

 

 

МИЭТ, СПИНТех, КАИ

Подпрограммы

 

8 / 29

Передача и возврат управления

 

 

 

 

 

 

 

 

 

jmp smem

передача управления (goto smem) smem ! ip

 

jCC smem

передача управления smem ! ip, если верно CC 2 flags

 

 

call smem

вызов подпрограммы

push ip;

smem ! ip

 

 

ret

возврат

pop ip

 

 

 

 

ret imm16

возврат с чисткой стека

pop ip;

sp += imm16

 

Флаги: не изменяются

 

 

: : :

 

 

sp

 

: : :

 

 

 

 

: : :

 

 

 

 

: : :

 

 

sp

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Стек

 

 

 

 

 

 

ci+1

 

 

sp

 

ci+1

 

 

sp

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

: : :

 

 

 

 

: : :

 

 

 

 

: : :

 

 

 

 

: : :

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

ret

 

 

 

 

ret

 

 

 

 

ret

 

 

ip

 

ret

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

: : :

 

 

f()

 

: : :

 

 

 

 

: : :

 

 

 

 

: : :

 

 

 

Код

f :

 

 

 

 

f :

 

 

 

ip

f :

 

 

 

 

f :

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

: : :

 

 

 

 

: : :

 

 

 

 

: : :

 

 

 

 

: : :

 

 

 

 

ci+1 :

 

 

 

 

ci+1 :

 

 

 

 

ci+1 :

 

 

 

 

ci+1 :

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

ip

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

ci :

call f

 

 

ip

ci :

call f

 

 

 

ci :

call f

 

 

 

ci :

call f

 

 

 

 

 

 

 

 

 

 

 

 

адреса растут снизу вверх

а) б) в) г)

Подпрограммы

Передача и возврат управления

Локальные переменные

Вызов функции ЯВУ

Совмещение C++ и ассемблера

Соглашения о вызовах (32 бита)

Искажение имён

Соглашения о вызовах (64 бита)

Про платформы

 

 

МИЭТ, СПИНТех, КАИ

 

Подпрограммы

9 / 29

Вызов функции ЯВУ

 

 

 

 

Требования к вызовам подпрограммы (в т. ч. функции ЯВУ)

 

1

передача управления на произвольный адрес;

 

2

возврат управления назад после завершения подпрограммы;

 

3

вложенные вызовы подпрограмм;

 

4

сохранение и восстановление регистров вызывающей программы;

 

5

передача заданного количества аргументов;

 

6

передача и возврат структур;

 

 

7выделение и освобождение памяти под локальные переменные подпрограмм.

1-3 call/ret, 4-6 соглашения, 7 традиции (пролог/эпилог).

 

Соглашение о вызовах

 

1

способ передачи аргументов (через регистры, через стек, смешанный);

2

порядок в стеке (Pascal первый помещается первым, C последним);

3

кто очищает стек и сохраняет/восстанавливает регистры (и какие).

 

Возвращаемое значение:

1 целое или указатель A (D : A);

2

вещественное st(0) (32-битный режим), xmm0=ymm0=zmm0 (64).

Подпрограммы

Передача и возврат управления

Локальные переменные

Вызов функции ЯВУ

Совмещение C++ и ассемблера

Соглашения о вызовах (32 бита)

Искажение имён

Соглашения о вызовах (64 бита)

Про платформы

 

 

 

МИЭТ, СПИНТех, КАИ

 

Подпрограммы

 

 

 

 

 

 

10 / 29

 

Соглашения о вызовах (32 бита)

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Соглашение

Параметры

Порядок

 

Выр.sp

 

Очистка стека

Изменяемые

Неизменяемые регистры

Результат

 

 

 

 

 

 

 

 

 

 

 

 

в регистрах

в стеке

 

 

 

регистры

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

cdecl

 

C

 

на 16)

 

вызывающая

 

 

 

 

 

 

 

 

 

st(0)

 

 

 

 

 

 

 

программа

eax;

 

 

 

 

 

 

pascal

 

Pascal

 

 

функция

ecx; edx;

 

 

 

 

 

 

 

 

 

 

 

 

 

 

st(0) st(7);

 

=

 

 

winapi

 

C

 

 

функция

ebx; ebp;

 

 

(stdcall)

 

 

 

MacOS X

 

 

 

 

xmm;

esi; edi

=edx:eax

 

 

gnu

 

C

 

 

this функция,

ymm;

 

 

 

 

 

 

 

 

 

 

 

вызывающая

zmm;

 

 

 

 

 

 

 

 

 

 

 

 

остальные

 

 

 

 

 

 

 

 

 

 

 

байта(в

 

программа

 

 

 

 

 

 

 

 

 

eax

 

 

gnu fastcall

ecx; edx

C

 

 

функция

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

gnu

eax; edx; ecx

C

 

 

 

функция

 

 

 

 

 

 

 

 

 

 

 

 

regparm(3)

 

 

 

4

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Borland

ecx; edx

Pascal

 

на

 

функция

 

 

 

 

 

 

 

 

 

 

 

 

fastcall

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Microsoft

ecx; edx

C

 

 

 

функция

 

 

 

 

 

 

 

 

 

 

 

 

fastcall

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Подпрограммы

 

Передача и возврат управления

 

 

 

 

 

 

 

 

Локальные переменные

 

 

 

 

 

 

 

 

 

 

Вызов функции ЯВУ

 

 

 

 

 

 

 

 

Совмещение C++ и ассемблера

 

 

 

 

 

 

 

 

 

 

Соглашения о вызовах (32 бита)

 

 

 

 

 

 

 

 

 

Искажение имён

 

 

 

 

 

 

 

 

 

 

 

Соглашения о вызовах (64 бита)

 

 

 

 

 

 

 

 

 

Про платформы

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

МИЭТ, СПИНТех, КАИ

 

 

Подпрограммы

 

 

 

11 / 29

 

 

Соглашения о вызовах (64 бита)

 

 

 

 

 

 

ОС

Соглашение

Параметры в регистрах

Порядок в стеке

Выр. sp

перед call

Очистка стека

Особенности работы со стеком

Изменяемые регистры

Неизменяемые регистры

Результат

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

X)

64MicrosoftSystem V amd64 psABI

rdi; rsi;

 

байт16наили32(на64, если через стек

или32передаётся64-байтовое целое)

вызывающаяпрограмма

красная зона 128

rax; rcx; rdx;

rbx; rbp;

rax;

 

 

WindowsMS

 

 

программа

частей 6 15

 

 

 

 

 

BSD GNU/Linux, OS Mac (включая

 

rdx; rcx; r8; r9;

 

 

 

 

 

байт над стеком

rsi; rdi;

r12 r15

rdx:rax,

 

 

 

xmm0 xmm7

C

 

 

 

 

прерываниями

r8 r11;

 

 

xmm0,

 

 

 

при переменном

 

 

 

 

 

и системными

st(0) st(7);

 

 

st(0)

 

 

 

кол-ве парам-в

 

 

 

 

 

вызовами)

 

 

 

 

 

 

(как в printf/scanf)

 

 

 

 

 

обеспечивает ОС

x=y=zmm

 

 

 

 

 

 

 

кол-во xmm

 

 

 

 

 

 

 

 

 

 

 

 

 

 

в al

 

 

 

 

 

 

 

 

 

 

 

 

 

 

rcx=xmm0;

 

 

 

 

 

теневые 32 байта

rax; rcx; rdx;

rbx; rbp;

rax;

 

 

 

 

rdx=xmm1;

 

 

 

 

 

под адресом

r8 r11;

rsi; rdi;

xmm0

 

 

 

 

 

 

 

 

 

возврата (но над

 

 

 

 

r8=xmm2;

 

 

 

 

 

стековыми

st(0) st(7);

r12 r15;

 

 

 

 

 

r9=xmm3

 

 

 

 

 

обеспечивает

x=y=zmm;

xmm6

 

 

 

 

 

 

 

 

 

 

 

параметрами)

 

 

 

 

 

 

 

 

 

 

 

 

 

 

вызывающая

кроме младших

xmm15

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Перед call sp = 16x ! после входа в функцию sp = 16x 8 (64-битный адрес возврата)

Подпрограммы

Передача и возврат управления

Локальные переменные

Вызов функции ЯВУ

Совмещение C++ и ассемблера

Соглашения о вызовах (32 бита)

Искажение имён

Соглашения о вызовах (64 бита)

Про платформы

 

Соседние файлы в папке АВС