mirror of
https://github.com/0xAX/linux-insides
synced 2024-11-17 15:29:56 +00:00
Update linux-bootstrap-2.md
This commit is contained in:
parent
f395064490
commit
c8a7622701
@ -212,7 +212,7 @@ ENDPROC(memcpy)
|
|||||||
|
|
||||||
Да, мы только что перешли в C-код и снова вернулись к ассемблеру :) Прежде всего мы видим, что `memcpy` и другие подпрограммы, расположенные здесь, начинаются и заканчиваются двумя макросами: `GLOBAL` и `ENDPROC`. Макрос `GLOBAL` описан в [arch/x86/include/asm/linkage.h](https://github.com/torvalds/linux/blob/16f73eb02d7e1765ccab3d2018e0bd98eb93d973/arch/x86/include/asm/linkage.h) и определяет директиву `globl`, а так же метку для него. `ENDPROC` описан в [include/linux/linkage.h](https://github.com/torvalds/linux/blob/16f73eb02d7e1765ccab3d2018e0bd98eb93d973/include/linux/linkage.h); отмечает символ `name` в качестве имени функции и заканчивается размером символа `name`.
|
Да, мы только что перешли в C-код и снова вернулись к ассемблеру :) Прежде всего мы видим, что `memcpy` и другие подпрограммы, расположенные здесь, начинаются и заканчиваются двумя макросами: `GLOBAL` и `ENDPROC`. Макрос `GLOBAL` описан в [arch/x86/include/asm/linkage.h](https://github.com/torvalds/linux/blob/16f73eb02d7e1765ccab3d2018e0bd98eb93d973/arch/x86/include/asm/linkage.h) и определяет директиву `globl`, а так же метку для него. `ENDPROC` описан в [include/linux/linkage.h](https://github.com/torvalds/linux/blob/16f73eb02d7e1765ccab3d2018e0bd98eb93d973/include/linux/linkage.h); отмечает символ `name` в качестве имени функции и заканчивается размером символа `name`.
|
||||||
|
|
||||||
Реализация `memcpy` достаточно проста. Во-первых, она помещает значения регистров `si` и `di` в стек для их сохранения, так как они будут меняться в течении работы. `memcpy` (как и другие функции в copy.S) использует `fastcall` соглашения о вызовах. Таким образом, она получает свои входные параметры из регистров `ax`, `dx` и `cx`. Вызов `memcpy` выглядит следующим образом:
|
Реализация `memcpy` достаточно проста. Во-первых, она помещает значения регистров `si` и `di` в стек для их сохранения, так как они будут меняться в течении работы. Как мы видим из `REALMODE_CFLAGS` в `arch/x86/Makefile` система сборки ядра использует параметр GCC `-mregparm = 3`, поэтому функции получают первые три параметра из регистров `ax`, `dx` и `cx`. Вызов `memcpy` выглядит следующим образом:
|
||||||
|
|
||||||
```c
|
```c
|
||||||
memcpy(&boot_params.hdr, &hdr, sizeof hdr);
|
memcpy(&boot_params.hdr, &hdr, sizeof hdr);
|
||||||
@ -304,7 +304,7 @@ GLOBAL(memset)
|
|||||||
retl
|
retl
|
||||||
ENDPROC(memset)
|
ENDPROC(memset)
|
||||||
```
|
```
|
||||||
Как мы можем видеть, `memset` использует `fastcall` соглашения о вызовах, так же как и `memcpy`: это означает, что функция получает свои параметры из регистров `ax`, `dx` и `cx`.
|
Как мы можем видеть, `memset` использует тоже самое соглашение о вызовах, как и `memcpy`: это означает, что функция получает свои параметры из регистров `ax`, `dx` и `cx`.
|
||||||
|
|
||||||
Как правило, реализация `memset` подобна реализации `memcpy`. Она сохраняет значение регистра `di` в стеке и помещает значение `ax` в `di`, которое является адресом структуры `biosregs`. Далее идёт инструкция `movzbl`, которая копирует значение `dl` в нижние 2 байта регистра `eax`. Оставшиеся 2 верхних байта `eax` будут заполнены нулями.
|
Как правило, реализация `memset` подобна реализации `memcpy`. Она сохраняет значение регистра `di` в стеке и помещает значение `ax` в `di`, которое является адресом структуры `biosregs`. Далее идёт инструкция `movzbl`, которая копирует значение `dl` в нижние 2 байта регистра `eax`. Оставшиеся 2 верхних байта `eax` будут заполнены нулями.
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user