x86 汇编语言数组
最近编写了6 个关于 x86 的 x86 组件的传奇故事,并考虑了计算机架构和程序的低级设计,涉及极简多线程 Web 服务器。
在整个过程中,阿卡贝·德·拉多·阿尔贡斯(Lado Alguns)对后部重要的事情感到满意,在传奇故事中,我要注意的是,我最重要的是。考虑到这一点,我们可以通过线程池来实现。
如果文件已被删除,则不可避免地会删除数组并组织计算机的内存。
在此过程中,您可以了解内存操作、注册器和内存堆的基本原理,并长期实现数组。
您可以使用熟悉的 x86 和 GDB 组件。 Caso não tenha,推荐加强休闲传奇。
议程
数组不存在
数组不存在。简单的阿西姆。
Como vimos naparte IV da saga,一个关于连续形式的记忆和组织,作为外文的信息。
声明以下信息的后续序列:
1, 2, 'H', 0
Eu sei,eu sei,os Tipos estão Misturados,mas isto não importa para este momento。全部内容 1 字节
Em assembly x86(vamos chamar de asm no Restante do artigo),podemos 声明了以下信息:
section .data
stuff: db 0x1, 0x2, 0x48, 0x0
Lembrando que o 字符 'H' na tabela ASCII 表示 0x48 em 十六进制
为了方便gdb调试,可以确认十六进制的顺序,而不是顺序排列的顺序stuff:
# Leitura do primeiro hexabyte em stuff
(gdb) x/1xb (void*) &stuff
0x402000 <stuff>: 0x01
# Leitura do segundo hexabyte em stuff
(gdb) x/1xb (void*) &stuff+1
0x402001: 0x02
# Leitura do terceiro hexabyte em stuff
(gdb) x/1xb (void*) &stuff+2
0x402002: 0x48
0x48使用字符串格式表示十六进制的 Podemos tambémx/s
(gdb) x/s (void*) &stuff+2
0x402002: "H"
É tudo hexadecimal!
com isto,caso queiramos 表示字符串“Hello”,de acordo com 表示 tabela ASCII,poderia ficar assim:
section .data
msg: db 0x48, 0x65, 0x6C, 0x6C, 0x6F, 0x0
没有 gdb vamos 验证代表字符串的规则msg:
(gdb) x/s &msg
0x402000 <msg>: "Hello"
Em asm, é possível declarar a string já com a representação dieta da tabelas ASCII:
section .data
msg: db "Hello", 0x0
; é o mesmo que
; msg: db 0x48, 0x65, 0x6C, 0x6C, 0x6F, 0x0
Strings também não existem
您可以使用十六进制的内存。嗯,数组,assim 和字符串,是一个简单的序列,用于存储内存中的数据。
字符串与“特殊数组”不同,它们代表 ASCII 字符(注意,字符串和数组的终止符代表字节“最终”):
O 数组可能很简单
接下来是一个简单的数组实现,我们将继续探索后续的过程:
global _start
%define SYS_exit 60
%define EXIT_SUCCESS 0
section .data
array: db 1, 2, 3, 0
section .text
_start:
mov al, [array] ; array[0]
mov bl, [array + 1] ; array[1]
mov cl, [array + 2] ; array[2]
mov sil, [array + 3] ; array[3]
.exit:
mov rdi, EXIT_SUCCESS
mov rax, SYS_exit
syscall
在初始化时.data,声明 um 数组为 1 字节 cada 的 3 个元素(inteiros de 1 a 3),使用数字 0 来作为数组的终点:
section .data
array: db 1, 2, 3, 0
接下来,.text程序的源代码、使用方法、配置或注册者结果的数组元素的获取方式如下:
section .text
_start:
mov al, [array] ; array[0]
如果没有注册器 (AL) 的记录和配置或结果,则无法继续升级0x402000或继续使用 1 字节的注册器,否则,将无法配置存储和配置的注册器或初始字节数组。
Vamos conferir com gdb:
# O array está armazenado no endereço 0x402000
# e contém o valor em hexa 0x00 0x03 0x02 0x01,
# lembrando que esta arquitetura utiliza o formato little-endian
(gdb) x &array
0x402000 <array>: 0x00030201
(gdb) b 13
(gdb) run
(gdb) next
# No registrador AL temos o primeiro elemento do array
(gdb) i r al
al 0x1 1
# É o mesmo que acessar o primeiro hexabyte contido no endereço
# 0x402000
(gdb) x/1xb 0x402000
0x402000 <array>: 0x01
Lembrando 是注册器 AL 代表 8 位注册器 RAX 的主要概念,是 x86_64 架构中的 64 位总数
数组中的元素的扩展、连接器的排列和 1 字节注册器的配置:
mov al, [array] ; array[0] => 1
mov bl, [array + 1] ; array[1] => 2
mov cl, [array + 2] ; array[2] => 3
mov sil, [array + 3] ; array[3] => 0 (aqui termina o array)
使用数组而不是初始化
在集市上,我们声明了以下内容.data并进行了初始化。启动“恐龙”程序,声明一系列未初始化的数据。.bss
前面的示例中,我们声明了 4 个字节的数组,使用了resb“保留字节”指令,其中 3 个字节是数组元素的保留,并且用字节表示 0x0 来表示数组的终止符。
section .bss
array: resb 4 ; 3 bytes + 1 byte de término
没有 gdb,数组初始值是 0,指示值是 4 字节保留值:
(gdb) x &array
0x402004 <array>: 0x00000000
(gdb) x/4xb &array
0x402004 <array>: 0x00 0x00 0x00 0x00
没有任何其他的元素,请注意使用一些技巧,所有这些都不是在初始阶段之前的示例。
; Move o valor 1 para o primeiro byte do endereço de memória em array
mov byte [array], 1 ; array[0] = 1
Com gdb 确认没有渲染 0x402000 是数组,请注意字节 1:
(gdb) x &array
0x402000 <array>: 0x00000001
E se quisermos adicionar or valor 2 no próximo byte do array?
mov byte [array + 1], 2
(gdb) x &array
0x402000 <array>: 0x00000201
修复数组中的“索引”修改。在数组的初始位置,使用索引 0,在后续位置,使用索引 1,在终点数组上递增。
Seria muito complicado ficar manipulando índice 硬编码。 Precisamos de um ponteiro pararepresentar este índice。
Índice para o resgate
假设数组已为零,并在数组上存储内存,则声明以下内容.data:
section .bss
array: resb 4 ; 3 bytes + 1 byte de término
section .data
pointer: db 0
徽标、其他主要元素以及接下来的形式,请参阅?
mov byte [array + pointer], 1 ; array + 0
Ao rodar o programa, temos o seguinte erro:
src/live.asm:14: error: invalid effective address: multiple base segments
这可能会导致操作多个内存段的部分的错误,而不是数组和指针。
Para resolver isto, precisamos fazer manipulação de ponteiros com valores imediatos (que foi o caso anterior com número hard-coded) or com registradores:
; append(1)
mov al, byte [pointer]
mov byte [array + rax], 1 ; array + 0
- 初始指令移动初始字节连续,没有渲染
pointer和设备没有注册器 AL - 第二个指令是移动 valor imediato 1(数组元素)以渲染数组内存。对于 RAX(AL 版本的 64 位)来说,它
0x0代表了一种能力,它可以插入到数组中的原始字节中
E para armazenar o segundo elemento no array?
; append(2)
mov al, byte [pointer]
mov byte [array + rax], 2
没有 gdb,vamos 验证了以下内容:
(gdb) x &array
0x402004 <array>: 0x00000002
呃,哦…… Desta forma estamos sobrescrevendo o valor front。 Queremos na verdade que o ponteiro "ande", ou seja, precisa ser Incrementado em um byte para que o append(2)resulte com os 2 elementos no array.
请参阅INC解决此问题的说明:
mov al, byte [pointer] ; pointer -> 0
mov byte [array + rax], 1 ; array + 0
inc byte [pointer] ; pointer -> 1
mov al, byte [pointer]
mov byte [array + rax], 2 ; array + 1
(gdb) x &array
0x402004 <array>: 0x00000201
耶! Que dia maravilhoso!
Atingindo o limite do array
是否可以连续增加或限制阵列?
mov al, byte [pointer]
mov byte [array + rax], 1 ; array + 0
inc byte [pointer]
mov al, byte [pointer]
mov byte [array + rax], 2 ; array + 1
inc byte [pointer]
mov al, byte [pointer]
mov byte [array + rax], 3 ; array + 2
inc byte [pointer]
# Lendo os primeiros 4 hexabytes do array, temos a representação
# do array cheio com todos os espaços ocupados, lembrando que
# o último byte é o término do array
(gdb) x /4xb &array
0x402004 <array>: 0x01 0x02 0x03 0x00
# O ponteiro está no fim do array
(gdb) x &pointer
0x402000 <pointer>: 0x03
Maravilha,e se adicionar mais um elemento,nossoprograma deveria allowedir?
mov al, byte [pointer]
mov byte [array + rax], 4 ; array + 3
inc byte [pointer]
# Não deveríamos permitir que mais um elemento fosse adicionado,
# pois nosso array já estava cheio
(gdb) x /4xb &array
0x402004 <array>: 0x01 0x02 0x03 0x04
# O ponteiro está para além da capacidade array (not good...)
(gdb) x &pointer
0x402000 <pointer>: 0x04
Vamos utilizar um Jump condicional (explico mais sobre isto na saga ) para não allowedir que o elemento seja adicionado.如果不添加数组,请先验证是否不添加数组:
cmp byte [pointer], 3 ; verifica se o array está cheio
je .exit ; salta para a rotina .exit caso a flag seja levantada
Assim fica 或完整程序:
global _start
%define SYS_exit 60
%define EXIT_SUCCESS 0
section .bss
array: resb 4 ; 3 bytes + 1 byte de término
section .data
pointer: db 0
section .text
_start:
cmp byte [pointer], 3 ; verifica se o array está cheio
je .exit
mov al, byte [pointer]
mov byte [array + rax], 1 ; array + 0
inc byte [pointer]
cmp byte [pointer], 3 ; verifica se o array está cheio
je .exit
mov al, byte [pointer]
mov byte [array + rax], 2 ; array + 1
inc byte [pointer]
cmp byte [pointer], 3 ; verifica se o array está cheio
je .exit
mov al, byte [pointer]
mov byte [array + rax], 3 ; array + 2
inc byte [pointer]
cmp byte [pointer], 3 ; verifica se o array está cheio
je .exit
; não deveria permitir adicionar o quarto elemento,
; pois o array suporta até 3 elementos. desta forma,
; estaríamos escrevendo no endereço de memória de outros
; dados do programa
mov al, byte [pointer]
mov byte [array + rax], 4 ; array + 3
inc byte [pointer]
.exit:
mov rdi, EXIT_SUCCESS
mov rax, SYS_exit
syscall
(gdb) x &pointer
0x402000 <pointer>: 0x00000003
(gdb) x &array
0x402004 <array>: 0x00030201
Perfeito, vamos agora fazer um pequeno refactoring no código separando a lógica de appara uma subrotina:
global _start
%define SYS_exit 60
%define EXIT_SUCCESS 0
%define CAPACITY 3
section .bss
array: resb CAPACITY + 1
section .data
pointer: db 0
section .text
_start:
mov rdi, 1
call .append
mov rdi, 2
call .append
mov rdi, 3
call .append
mov rdi, 4
call .append
.exit:
mov rdi, EXIT_SUCCESS
mov rax, SYS_exit
syscall
.append:
cmp byte [pointer], CAPACITY ; verifica se o array está cheio
je .done
mov al, byte [pointer]
mov byte [array + rax], dil
inc byte [pointer]
.done:
ret
Se você quer entender mais sobre 条件跳转、 rotinas、 call、 ret e flags、 sugiro a leitura da minha saga que foi Referenciada diversas vezes Neste artigo
Executando com gdb e...
(gdb) x &array
0x402004 <array>: 0x00030201
(gdb) x &pointer
0x402000 <pointer>: 0x00000003
太棒了!
进入游戏后,我们需要重新调整数组以支持更多要素,或者进行一些动态调整。
是否有其他一些基本要素可以在记忆以外的区域中获得,但不能在数组中找到?
堆,堆,好耶!
堆中的元素与计算机程序内存的布局有关:
- 布局和表示计算机内存中的内存的渲染效果主要取决于直接编程的效果
- 记住所有的信息,接下来的内容
.text,以及有关程序的参考信息 - 您可以在以下内容中了解我们所考虑的初始信息
.data以及所代表的信息的后续内容.bss - 程序的主要内容、程序的堆栈、程序的参数、程序的名称、参数和程序的信息,以解决堆栈中的问题,并且可以从功能和参数方面来了解程序的信息。
- 堆栈的格式和“cresce pra baixo”,或者,符合堆栈中的元素,直接在内存中增加cresce
没有“meio”进行布局,进入堆栈的一部分,整个内存空间与堆相关。没有堆,从动态角度看,与动态角度不同。
Para acomodar um array de tamanho dinâmico que support redimensionamento (resize), temos de alocar memória nesta área.
接下来,我们将在堆栈中存储一些内存
Alocação dinâmica de memória com brk
通过操作该存储器和系统调用的格式,可以中断程序,然后终止数据。
com brk,可以修改某些程序,以实现更高的效果,或者允许对程序和文件夹中的内存区域进行操作。
首先,请先执行以下操作: 映射系统调用,然后执行以下操作:
%define SYS_brk 12
....
section .text
_start:
; syscall para acessar o program break (0x403000), que é onde termina
; a seção de dados e começa o heap
mov rdi, 0
mov rax, SYS_brk
syscall
....
Com gdb、vamos analisar 或 estado do 程序:
# Breakpoint na linha da syscall brk
(gdb) b 18
(gdb) run
# O início do programa fica na seção .text e começa com
# 0x401000
(gdb) x _start
0x401000 <_start>: 0x000000bf
# O pointer está na seção .data um pouco mais acima e começa com
# 0x402000
(gdb) x &pointer
0x402000 <pointer>: 0x00000000
# O array está na seção .bss um pouco mais acima e começa com
# 0x402004
(gdb) x &array
0x402004 <array>: 0x00000000
# Executa a syscall brk
(gdb) n
# A syscall brk armazena em RAX o endereço de memória do program break,
# no caso um pouco mais acima em 0x403000
(gdb) i r rax
rax 0x403000 4206592
0x401000:.text接下来是节目内容0x402000:.data以下内容为初始信息0x402004:.bss接下来的内容0x403000: 程序中断,然后终止在“堆”部分
这是一个在数组元素上渲染的部分0x403000,使用字节来渲染数组,在没有堆的情况下渲染数组元素。
Na syscall que fizemos, se o argumento em RDI tiver zero,significa que brk vai retornar o program break atual, no caso 0x403000.可以通过系统调用 brk com 或 RDI 不同的参数(增量)来解决程序中断问题。
市场上的一部分,在数组中.bss,最多可以保留 4 字节数组,需要 1 字节代表数组内存的存储:
global _start
%define SYS_brk 12
%define SYS_exit 60
%define EXIT_SUCCESS 0
%define CAPACITY 3
; inicialmente começa com 0x000000, mas depois irá conter
; o endereço 0x403000
section .bss
array: resb 1
section .data
pointer: db 0
section .text
_start:
mov rdi, 0
mov rax, SYS_brk
syscall
mov rdi, rax
add rdi, CAPACITY
mov rax, SYS_brk
syscall
...
...
Ao analisarmos com gdb:
# Breakpoint na primeira syscall
(gdb) b 18
(gdb) run
# Executa a linha da syscall
(gdb) n
# Em RAX a syscall armazena o endereço do program break, no caso
# 0x403000
(gdb) i r rax
rax 0x403000 4206592
(gdb) x 0x403000
0x403000: Cannot access memory at address 0x403000
接下来,我们将不再需要访问堆中的新字节。 Vamos 和 com 是 próxima 系统调用:
(gdb) n
(gdb) n
# Antes de executar a syscall, verificamos que o argumento RDI vai
# conter o endereço desejado para o novo program break, no caso com
# 3 bytes adicionados, 0x403003
(gdb) i r rdi
rdi 0x403003 4206595
# Executa a syscall...
(gdb) n
(gdb) n
# Após a execução da segunda syscall, vemos que em RAX, o program break foi alterado para 0x403003
(gdb) i r rax
rax 0x403003 4206595
集市,可获取记忆中的信息0x403000:0x403003
(gdb) x 0x403000
0x403000: 0x00000000
(gdb) x 0x403001
0x403001: 0x00000000
(gdb) x 0x403002
0x403002: 0x00000000
(gdb) x 0x403003
0x403003: 0x00000000
呜! Agora temos no heap uma área reservada especialmente para o nosso querido array, olha que coisa!
可以操作或阵列存储内存吗?
蓬泰罗斯,到处都是蓬泰罗斯
作为一个 Primeira 系统调用,开发者可以渲染代表0x403000Primeiro 程序中断的内存,并在数组中设置以下内容.bss:
...
mov rdi, 0
mov rax, SYS_brk
syscall
mov [array], rax ; <---- breakpoint aqui
mov rdi, rax
add rdi, CAPACITY
mov rax, SYS_brk
syscall
...
Vamos verificar com gdb o 断点 na linha que muda o ponteiro do array:
(gdb) b 19
(gdb) run
(gdb) x &array
0x402004 <array>: 0x00000000
# Executa a linha que muda o ponteiro
(gdb) n
# Agora o ponteiro aponta para o endereço 0x403000,
# é isto o que queremos
(gdb) x &array
0x402004 <array>: 0x00403000
重要的是,数组0x402004在堆中是不存在的,.bss接下来,它的作用代表了记忆的结束,0x403000这是在堆中首次出现的元素。
Agora 提供了一个 3 字节无堆的 proxima 系统调用,程序中断服务修改和操作操作或数组点和连接器的连接。
在第二个系统调用中,您可以操作array自己的勇气,在广场上或在阵列中进行勇气,并从记忆中的元素中获得乐趣。
实际可用程序:
global _start
%define SYS_brk 12
%define SYS_exit 60
%define EXIT_SUCCESS 0
%define CAPACITY 3
section .bss
array: resb 1 ; 0x403000
section .data
pointer: db 0
section .text
_start:
mov rdi, 0
mov rax, SYS_brk
syscall
mov [array], rax
mov rdi, rax
add rdi, CAPACITY
mov rax, SYS_brk
syscall
mov rbx, [array]
mov r8, 1
call .append
mov r8, 2
call .append
mov r8, 3
call .append
mov r8, 4
call .append
.exit:
mov rdi, EXIT_SUCCESS
mov rax, SYS_exit
syscall
.append:
cmp byte [pointer], CAPACITY ; verifica se o array está cheio
je .done
mov sil, byte [pointer]
mov byte [rbx + rsi], r8b
inc byte [pointer]
.done:
ret
Explicando cada bloco:
mov rdi, 0
mov rax, SYS_brk
syscall
mov [array], rax
- Busca o 程序中断 atual e armazena o endereço no ponteiro
array
mov rdi, rax
add rdi, CAPACITY
mov rax, SYS_brk
syscall
- 修改程序中断,增量 3 字节,初始容量为数组,无堆
; atribuir ao registrador o endereço de memória ao qual o
; ponteiro "array" está apontando
mov rbx, [array]
- 设备或 RBX 注册器记忆的渲染。必须注意的是,必须有足够的权限
.bss才能获得许可
mov r8, 1
call .append
- 如果您使用 RDI 来使用系统调用,则可以使用 RDI 注册器来代表元素和辅助功能,但不可以使用 R8 注册器
.append:
cmp byte [pointer], CAPACITY ; verifica se o array está cheio
je .done
mov sil, byte [pointer]
mov byte [rbx + rsi], r8b ; indirect-mode addressing
inc byte [pointer]
.done:
ret
Agora.append可以对注册器 RBX 的数组操作进行修改,无需堆存储。您可以使用注册器 RAX 来代表 ponteiro pois 系统调用,以恢复程序中断;嵌套 caso trocamos para o RSI(que tem o SIL como suarepresentação de 8-bits menores)。
通过 gdb 执行程序,验证元素的发送方式,无需执行0x403000堆操作,无需注册 RBX 即可使用设备:
# Array aponta para o endereço 0x403000
(gdb) x &array
0x402004 <array>: 0x00403000
# No endereço, temos os elementos adicionados. Yay!
(gdb) x 0x403000
0x403000: 0x00030201
# E o ponteiro de "índice" corretamente representando o fim do array no heap
(gdb) x &pointer
0x402000 <pointer>: 0x00000003
稍后,我们将介绍前组的示例.bss,但不允许使用其他任何元素或组中的任何限制。
Vamos mudar isto,重新调整尺寸并允许新的元素加入爱好者。
调整 com brk
接下来,首先要重新调整尺寸,以限制能力。 Começamos por alterar a rotina .append:
.append:
cmp byte [pointer], CAPACITY ; verifica se o array está cheio
je .resize
mov sil, byte [pointer]
mov byte [rbx + rsi], r8b
inc byte [pointer]
.done:
ret
.resize:
...
在所有的.doneestiver cheio 中进行 fazer 跳跃,在 sub-rotina chamada 外跳跃.resize,然后将 syscall 放入 novamente,修改 assim 或程序中断uma nova are na memória,首先执行数组的操作:
.append:
cmp byte [pointer], CAPACITY ; verifica se o array está cheio
je .resize
mov sil, byte [pointer]
mov byte [rbx + rsi], r8b
inc byte [pointer]
.done:
ret
.resize:
mov rdi, 0
mov rax, SYS_brk
syscall
mov rdi, rax ; RDI passa a representar o break atual
add rdi, CAPACITY ; adiciona 3 bytes, ficando 0x403006
mov rax, SYS_brk
syscall
jmp .append
- 调整大小或中断实际大小的初始系统调用,不能进行任何更改
0x403003,不能启动数组程序 - 调整大小修改或中断的第二个系统调用,alocando assim mais 3 字节无堆
- 调整大小、返回功能、启动并
.append执行必要的逻辑或无数组元素
下一步,新的操作按钮将存储在无阵列的附加信息中,并修改为可用的名称。
Se executarmos o programa exatamente assim, vamos enfrentar um Problema, pois:
- a cada vez que éfeito or resize, salta para o início da rotina
- 验证或阵列 (pointeiro) 为初始容量,但不包括 3. 为 valor 3 提供支持,进入新版本后无需调整角色大小,无限循环可无限调整记忆大小
解析器是,precisamos comparar o 指针com a capacidade atual(modificada),e portanto vamos adicionar um valor na seção .dataquerepresenta a capacidade atual:
%define CAPACITY 3
section .data
pointer: db 0
currentCapacity: db CAPACITY ; começa com 3
如果.append您需要进行比较、调整大小、进行修改、永久修复程序或程序的初始值,则可以进行调整。currentCapacityCAPACITY
.append:
mov r9, [currentCapacity]
cmp byte [pointer], r9b ; verifica se o array está cheio
je .resize
...
E, após or redimensionamento antes de voltar pro .append, vamos Incrementar or valor da capacidade inicial à capacidade atual:
.resize:
mov rdi, 0
mov rax, SYS_brk
syscall
mov rdi, rax
add rdi, CAPACITY
mov rax, SYS_brk
syscall
mov r10, currentCapacity
add byte [r10], CAPACITY
jmp .append
如果执行程序,则可以在 4 个元素中成功执行,无需重新调整尺寸:
(gdb) x 0x403000
0x403000: 0x04030201
是否有一些额外的建议或元素?
...
mov r8, 4
call .append
mov r8, 5
call .append
mov r8, 6
call .append
mov r8, 7
call .append
...
# Podemos ver que o currentCapacity é 9, ou seja, foram feitos
# 2 redimensionamentos. Nosso array consegue agora acomodar até 9 elementos,
# pelo que ao adicionar o décimo elemento, mais um resize seria feito.
(gdb) x ¤tCapacity
0x402001 <currentCapacity>: 0x09
# Buscando os 9 primeiros hexabytes no endereço do array no heap
(gdb) x/9xb 0x403000
0x403000: 0x01 0x02 0x03 0x04 0x05 0x06 0x07 0x00
0x403008: 0x00
这也太酷了吧?
最终程序
最后一个程序是,使用 3 个元素的初始数组来重新调整系统调用的大小brk,并与数组元素保持一致:
global _start
%define SYS_brk 12
%define SYS_exit 60
%define EXIT_SUCCESS 0
%define CAPACITY 3
section .bss
array: resb 1
section .data
pointer: db 0
currentCapacity: db CAPACITY ; capacidade inicial é 3
section .text
_start:
mov rdi, 0
mov rax, SYS_brk
syscall
mov [array], rax
mov rdi, rax
add rdi, CAPACITY
mov rax, SYS_brk
syscall
mov rbx, [array]
mov r8, 1
call .append
mov r8, 2
call .append
mov r8, 3
call .append
mov r8, 4
call .append
mov r8, 5
call .append
mov r8, 6
call .append
mov r8, 7
call .append
.exit:
mov rdi, EXIT_SUCCESS
mov rax, SYS_exit
syscall
.append:
mov r9, [currentCapacity]
cmp byte [pointer], r9b ; verifica se o array está cheio
je .resize
mov sil, byte [pointer]
mov byte [rbx + rsi], r8b
inc byte [pointer]
.done:
ret
.resize:
mov rdi, 0
mov rax, SYS_brk
syscall
mov rdi, rax
add rdi, CAPACITY
mov rax, SYS_brk
syscall
mov r10, currentCapacity
add byte [r10], CAPACITY
jmp .append
结论
下一步,您将在 Assembly x86 中实现阵列,并了解重要的内存布局、注册操作和内存分配brk。
作为未来的基础,您可以假装使用文件和后面的列表来实现连接。
敬请关注!
参考资料
寻址模式
https://www.tutorialspoint.com/assembly_programming/assembly_addressing_modes.htm
系统调用 brk
https://man7.org/linux/man-pages/man2/brk.2.html
ASCII 字符表
https://www.asciicharstable.com/_site_media/ascii/ascii-chars-table-landscape.jpg





