mirror of
https://github.com/0xAX/linux-insides.git
synced 2024-11-19 22:48:13 +00:00
alignment fixed
Signed-off-by: Alexander Kuleshov <kuleshovmail@gmail.com>
This commit is contained in:
parent
4d6e7f98c3
commit
cd93ea62ea
@ -180,10 +180,10 @@ label: pop %reg
|
||||
После этого регистр `%reg` будет содержать адрес метки. Давайте посмотрим на аналогичный код поиска адреса `startup_32` в ядре Linux:
|
||||
|
||||
```assembly
|
||||
leal (BP_scratch+4)(%esi), %esp
|
||||
call 1f
|
||||
1: popl %ebp
|
||||
subl $1b, %ebp
|
||||
leal (BP_scratch+4)(%esi), %esp
|
||||
call 1f
|
||||
1: popl %ebp
|
||||
subl $1b, %ebp
|
||||
```
|
||||
|
||||
Как вы помните из предыдущей части, регистр `esi` содержит адрес структуры [boot_params](https://github.com/torvalds/linux/blob/16f73eb02d7e1765ccab3d2018e0bd98eb93d973/arch/x86/include/uapi/asm/bootparam.h#L113), которая была заполнена до перехода в защищённый режим. Структура `boot_params` содержит специальное поле `scratch` со смещением `0x1e4`. Это 4 байтное поле будет временным стеком для инструкции `call`. Мы получаем адрес поля `scratch` + `4` байта и помещаем его в регистр `esp`. Мы добавили `4` байта к базовому адресу поля `BP_scratch`, поскольку поле является временным стеком, а стек на архитектуре `x86_64` растёт сверху вниз. Таким образом, наш указатель стека будет указывать на вершину стека. Далее мы видим наш шаблон, который я описал ранее. Мы переходим на метку `1f` и помещаем её адрес в регистр `ebp`, потому что после выполнения инструкции `call` на вершине стека находится адрес возврата. Теперь у нас есть адрес метки `1f` и мы легко сможем получить адрес `startup_32`. Нам просто нужно вычесть адрес метки из адреса, который мы получили из стека:
|
||||
|
Loading…
Reference in New Issue
Block a user