Адреса функции известны ещё на этапе компиляции
Мне нужно считывать из файла строки с пробелами, оканчивающиеся символом переноса
scanf("%[^\n] ", str);
(заметь пробел после форматной строки, извлекающий символ конца строки на котором остановился матчинг), и знать, что строка считана в str, но конец строки в неё не попал. Но, точно "Полные копии всех состояний не хранятся".
$ git init .
$ hexdump -Cv /dev/urandom | head -n 100000 > a
$ stat a
File: a
Size: 7900000 Blocks: 15432 IO Block: 4096 regular file
$ git add a
$ git commit -m 'version 1'
[master (root-commit) b36ee5cb126b] version 1
1 file changed, 100000 insertions(+)
create mode 100644 a
$ git cat-file -p b36ee5cb126b
tree f5870cee82fda72446a4dd3be8ebaeffe46035a3
author <jcmvbkbc@gmail.com> 1679909736 -0700
committer <jcmvbkbc@gmail.com> 1679909736 -0700
version 1
$ git cat-file -p f5870cee82fda72446a4dd3be8ebaeffe46035a3
100644 blob 65a9d4359a613ac58723324b2da83294673ca018 a
$ stat .git/objects/65/a9d4359a613ac58723324b2da83294673ca018
File: .git/objects/65/a9d4359a613ac58723324b2da83294673ca018
Size: 4090218 Blocks: 7992 IO Block: 4096 regular file
$ echo 'some more data' >> a
$ git commit -a -m 'version 2'
[master 73e8c999ed23] version 2
1 file changed, 1 insertion(+)
$ git cat-file -p 73e8c999ed23
tree 57ce1455664bd5027552860b713779c226c70fe9
parent b36ee5cb126b84100984c5b44f6d1f39155bd747
author <jcmvbkbc@gmail.com> 1679909809 -0700
committer <jcmvbkbc@gmail.com> 1679909809 -0700
version 2
$ git cat-file -p 57ce1455664bd5027552860b713779c226c70fe9
100644 blob 22f30336c84a6f20376a83fc04977797969f80b4 a
$ stat .git/objects/22/f30336c84a6f20376a83fc04977797969f80b4
File: .git/objects/22/f30336c84a6f20376a83fc04977797969f80b4
Size: 4090233 Blocks: 7992 IO Block: 4096 regular file
$ for a in `seq 3 100` ; do echo 'some more data' >> a ; git commit -a -m "version $a" ; done
...
$ du -sh .git/objects/
392M .git/objects/
по данной вами же ссылке написано
Первоначальный формат для сохранения объектов в Git называется «рыхлым» форматом (loose format). Однако, время от времени Git упаковывает несколько таких объектов в один pack-файл для сохранения места на диске и повышения эффективности.
это больше исключение
Гит хранит разницу состояний между коммитами – diff.
любой доступ к памяти, нужно в любом случае, обратится к tlb
в любом случае, это вызов функции с передачей параметров, и разбор адреса на n кусков, пара проверок.
-d in_asm, op_opt,out_asm
movb (%rbx), %al
jmp 1f
1:
IN:
0x001000ee: 8a 03 movb (%rbx), %al
0x001000f0: eb 00 jmp 0x1000f2
OP after optimization and liveness analysis:
ld_i32 tmp11,env,$0xfffffffffffffff0 dead: 1 pref=0xffff
movi_i32 tmp12,$0x0 pref=0xffff
brcond_i32 tmp11,tmp12,lt,$L0 dead: 0 1
---- 00000000001000ee 0000000000000000
qemu_ld_i64 tmp0,rbx,ub,2 dead: 1 pref=0xf
deposit_i64 rax,rax,tmp0,$0x0,$0x8 sync: 0 dead: 0 1 2 pref=0xffff
---- 00000000001000f0 0000000000000000
goto_tb $0x0
movi_i64 tmp3,$0x1000f2 pref=0xffff
st_i64 tmp3,env,$0x80 dead: 0 1
exit_tb $0x7f02d017d480
set_label $L0
exit_tb $0x7f02d017d483
OUT: [size=152]
-- guest addr 0x00000000001000ee + tb prologue
0x7f02d017d540: 8b 5d f0 movl -0x10(%rbp), %ebx
0x7f02d017d543: 85 db testl %ebx, %ebx
0x7f02d017d545: 0f 8c 58 00 00 00 jl 0x7f02d017d5a3
0x7f02d017d54b: 48 8b 5d 18 movq 0x18(%rbp), %rbx
0x7f02d017d54f: 48 8b fb movq %rbx, %rdi
0x7f02d017d552: 48 c1 ef 07 shrq $7, %rdi
0x7f02d017d556: 48 23 7d e0 andq -0x20(%rbp), %rdi
0x7f02d017d55a: 48 03 7d e8 addq -0x18(%rbp), %rdi
0x7f02d017d55e: 48 8b f3 movq %rbx, %rsi
0x7f02d017d561: 48 81 e6 00 f0 ff ff andq $0xfffffffffffff000, %rsi
0x7f02d017d568: 48 3b 37 cmpq (%rdi), %rsi
0x7f02d017d56b: 48 8b f3 movq %rbx, %rsi
0x7f02d017d56e: 0f 85 3b 00 00 00 jne 0x7f02d017d5af
0x7f02d017d574: 48 03 77 18 addq 0x18(%rdi), %rsi
0x7f02d017d578: 0f b6 1e movzbl (%rsi), %ebx
0x7f02d017d57b: 48 8b 4d 00 movq (%rbp), %rcx
0x7f02d017d57f: 88 d9 movb %bl, %cl
0x7f02d017d581: 48 89 4d 00 movq %rcx, (%rbp)
-- guest addr 0x00000000001000f0
0x7f02d017d585: 66 90 nop
0x7f02d017d587: e9 00 00 00 00 jmp 0x7f02d017d58c
0x7f02d017d58c: 48 c7 85 80 00 00 00 f2 movq $0x1000f2, 0x80(%rbp)
0x7f02d017d594: 00 10 00
0x7f02d017d597: 48 8d 05 e2 fe ff ff leaq -0x11e(%rip), %rax
0x7f02d017d59e: e9 75 2a e8 ff jmp 0x7f02d0000018
0x7f02d017d5a3: 48 8d 05 d9 fe ff ff leaq -0x127(%rip), %rax
0x7f02d017d5aa: e9 69 2a e8 ff jmp 0x7f02d0000018
-- tb slow paths + alignment
0x7f02d017d5af: 48 8b fd movq %rbp, %rdi
0x7f02d017d5b2: ba 02 00 00 00 movl $2, %edx
0x7f02d017d5b7: 48 8d 0d bd ff ff ff leaq -0x43(%rip), %rcx
0x7f02d017d5be: ff 15 0c 00 00 00 callq *0xc(%rip)
0x7f02d017d5c4: 8b d8 movl %eax, %ebx
0x7f02d017d5c6: e9 b0 ff ff ff jmp 0x7f02d017d57b
0x7f02d017d5cb: 90 nop
0x7f02d017d5cc: 90 nop
0x7f02d017d5cd: 90 nop
0x7f02d017d5ce: 90 nop
0x7f02d017d5cf: 90 nop
data: [size=8]
0x7f02d017d5d0: .quad 0x000055895af47e50
Загрузка регистра %rbx виртуального процессора в %rbx:
0x7f02d017d54b: 48 8b 5d 18 movq 0x18(%rbp), %rbx
Вычисление адреса записи в TLB QEMU для виртуального адреса в %rbx:
0x7f02d017d54f: 48 8b fb movq %rbx, %rdi
0x7f02d017d552: 48 c1 ef 07 shrq $7, %rdi
0x7f02d017d556: 48 23 7d e0 andq -0x20(%rbp), %rdi
0x7f02d017d55a: 48 03 7d e8 addq -0x18(%rbp), %rdi
Выделение адреса страницы из виртуального адреса в %rbx:
0x7f02d017d55e: 48 8b f3 movq %rbx, %rsi
0x7f02d017d561: 48 81 e6 00 f0 ff ff andq $0xfffffffffffff000, %rsi
Сравнение адреса страницы и виртуального адреса адреса в TLB
0x7f02d017d568: 48 3b 37 cmpq (%rdi), %rsi
Если не сходится -- перейти к вызову обработчика эмуляции TLB процессора:
0x7f02d017d56b: 48 8b f3 movq %rbx, %rsi
0x7f02d017d56e: 0f 85 3b 00 00 00 jne 0x7f02d017d5af
Иначе (сошлось) -- вычислить "физический" адрес по виртуальному:
0x7f02d017d574: 48 03 77 18 addq 0x18(%rdi), %rsi
Загрузить байт из памяти:
0x7f02d017d578: 0f b6 1e movzbl (%rsi), %ebx
Записать загруженный байт в регистр виртуального процессора %al:
0x7f02d017d57b: 48 8b 4d 00 movq (%rbp), %rcx
0x7f02d017d57f: 88 d9 movb %bl, %cl
0x7f02d017d581: 48 89 4d 00 movq %rcx, (%rbp)
Или есть какие обходы, когда игнорится трансляция, как будто в реальном режиме.
Или вот чтение инструкции из EIP, каждое чтение по адресу, прочесть инструкцию PC+1 будет перед тем как исполнить, на фазе извлечения опять это делать?
lspci -k