0% acharam este documento útil (0 voto)
107 visualizações43 páginas

Assembly NASM

Enviado por

Joao Victor
Direitos autorais
© © All Rights Reserved
Levamos muito a sério os direitos de conteúdo. Se você suspeita que este conteúdo é seu, reivindique-o aqui.
Formatos disponíveis
Baixe no formato PDF, TXT ou leia on-line no Scribd
0% acharam este documento útil (0 voto)
107 visualizações43 páginas

Assembly NASM

Enviado por

Joao Victor
Direitos autorais
© © All Rights Reserved
Levamos muito a sério os direitos de conteúdo. Se você suspeita que este conteúdo é seu, reivindique-o aqui.
Formatos disponíveis
Baixe no formato PDF, TXT ou leia on-line no Scribd
Você está na página 1/ 43

Assembly NASM

Assembly A linguagem assembly utiliza


códigos mnemônicos (ADD, SUB,
...), mais fáceis de aprender e
• Linguagem de baixo nível memorizar que os códigos
numéricos cada instrução tem
• Traduzida por assemblers uma correspondência de um-
para-um com as instruções em
• Baseada em mnemônicos linguagem de máquina.

• Assembly x86 diferente do MIPS


• Menos registradores
• Muitas operações podem ser feitas com dados na memória
• Maior abstração
Assemblers
• TurboASM - TASM
• MicrosoftASM – MASM
• NetwideASM - NASM
• Gratuito
• Unix
• Um assembler não compila o código de outro

Online: https://www.mycompiler.io/pt/new/asm-x86_64
Assemblers

•NASM: por que usar?


• Sintaxe menos poluída
• Mais abstrações
• Opensource
Registradores
• Registradores são elementos digitais com capacidade de
armazenar dados que se situam no processador.
• Divide-se em dois tipos
– Visíveis ao usuário;
– Controle e estado
• Podem ser acessados pelo usuário através das linguagens de
máquina ou de montagem;
Registradores
• São classificados em:
• Registrador de propósito geral;
– Podem ser usados para várias funções. Armazena dados e endereço. Em
alguns casos podem ser usados em tarefas especificas
• Registrador de dados;
– Dedicados ao armazenamento de dados
• Registrador de endereço;
– Dedicados ao armazenamento de endereço (segmento, índice ou pilha)
• Registrador de código de condição;
– Armazena bits que definem resultados de uma operação
NASM : Sections
• data
• Dados inicializados
– db ;Declara bytes
– equ ;Resolve uma expressão e inicializa a variável com o resultado
– dw ;Declara uma palavra que armazena um dado
• Ex:
section .data
message: db 'Hello world!’
msglen: que 12
buffersize: dw 1024
NASM : Sections
• bss
• Espaço reservado (variáveis)
– resb ;Reserva uma quantidade de bytes
– resw ;Reserva uma quantidade de palavras(2bytes)
– resq ;Reserva um array de numeros reais
• Ex:
section .bss
name: resb 255
bigNum: resw 1
realarray: resq 10
NASM : Sections
• text
• Onde o código assembly fica
• Ex:
section .text
global _start
_start:
POP EBX
.
.
.
NASM : Registradores
Name Notes Type 64-bit 32-bit 16-bit 8-bit
rax Values are returned from functions in this register. scratch rax eax ax ah and al
rcx Typical scratch register. Some instructions also use it as a counter. scratch rcx ecx cx ch and cl
rdx Scratch register. scratch rdx edx dx dh and dl
rbx Preserved register: don't use it without saving it! preserved rbx ebx bx bh and bl

rsp The stack pointer. Points to the top of the stack (details coming soon!) preserved rsp esp sp spl

Preserved register. Sometimes used to store the old value of the stack
rbp preserved rbp ebp bp bpl
pointer, or the "base".
Scratch register used to pass function argument #2 in 64-bit Linux. In 64-bit
rsi scratch rsi esi si sil
Windows, a preserved register.
Scratch register and function argument #1 in 64-bit Linux. In 64-bit
rdi scratch rdi edi di dil
Windows, a preserved register.
Scratch register. These were added in 64-bit mode, so they have numbers,
r8 scratch r8 r8d r8w r8b
not names.
r9 Scratch register. scratch r9 r9d r9w r9b
r10 Scratch register. scratch r10 r10d r10w r10b
r11 Scratch register. scratch r11 r11d r11w r11b

r12 Preserved register. You can use it, but you need to save and restore it. preserved r12 r12d r12w r12b

r13 Preserved register. preserved r13 r13d r13w r13b


r14 Preserved register. preserved r14 r14d r14w r14b
r15 Preserved register. preserved r15 r15d r15w r15b
16-
64-bit 32-bit 8-bit
bit
NASM : Registradores rax
rcx
eax
ecx
ax ah and al
cx ch and cl
dh and
rdx edx dx
dl
bh and
rbx ebx bx
bl
rsp esp sp spl
rbp ebp bp bpl
rsi esi si sil
rdi edi di dil
r8 r8d r8w r8b
r9 r9d r9w r9b
r10 r10d r10w r10b
r11 r11d r11w r11b
r12 r12d r12w r12b
r13 r13d r13w r13b
r14 r14d r14w r14b
r15 r15d r15w r15b
NASM : System Calls
%rax System Call %rdi %rsi %rdx %r10 %r8 %r9
0 sys_read unsigned int fd char *buf size_t count
1 sys_write unsigned int fd const char *buf size_t count
2 sys_open conts char *fileName int flags int mode
3 sys_close unsigned int fd
4 sys_stat conts char *fileName struct stat *statbuf
5 sys_fstat unsigned int fd struct stat *statbuf
fconts char
6 sys_lstat struct stat *statbuf
*fileName
long
7 sys_poll struct poll_fd *ufds unsigned int nfds
timeout_msecs
NASM : System Calls
NASM : Escrever uma Mensagem
• Definir o sys_write
• rax = 1 0 (entrada padrão)
• 1º parâmetro: rdi = 1 1 (saída padrão)
2 (erro)

• 2º parâmetro: rsi = ‘mensagem a ser imprimida’


• 3º parâmetro: rdx = quantidade de bytes que a mensagem ocupa
NASM: “Hello World” section .data
msg db "Hello world!"

sys_exit: section .text


– rax = 60 Código de erro global _start
– rdi = 0 0 (tudo certo)
1 (algo está errado)_start:
mov rax, 1 ; sys_write
mov rdi, 1 ; saída padrão
Imprime a mensagem mov rsi, msg
mov rdx, 12
syscall

mov rax, 60 ; sys_exit


Encerra o programa mov rdi, 0 ; código de erro (tudo certo)
syscall
NASM: “Hello World” section .data
com quebra de linha msg db "Hello world!“, 10

section .text
global _start

_start:
mov rax, 1 ; sys_write
mov rdi, 1 ; saída padrão
mov rsi, msg
mov rdx, 13
syscall

mov rax, 60 ; sys_exit


mov rdi, 0 ; código de erro (tudo certo)
syscall
NASM : Leitura de Dados
%rax System Call %rdi %rsi %rdx %r10 %r8 %r9
0 sys_read unsigned int fd char *buf size_t count
1 sys_write unsigned int fd const char *buf size_t count
2 sys_open conts char *fileName int flags int mode
3 sys_close unsigned int fd
4 sys_stat conts char *fileName struct stat *statbuf
5 sys_fstat unsigned int fd struct stat *statbuf
fconts char
6 sys_lstat struct stat *statbuf
*fileName
long
7 sys_poll struct poll_fd *ufds unsigned int nfds
timeout_msecs
NASM : Leitura de Dados
section .data _start: ; imprimir mensagem 2
mov rax, 1
msg1 db "Digite seu nome: ", 10 ; imprimir mensagem 1
mov rdi, 1
tam1 equ $-msg1 mov rax, 1
mov rsi, msg2
mov rdi, 1 mov rdx, tam2
msg2 db "Ola, " mov rsi, msg1 syscall

tam2 equ $-msg2 mov rdx, tam1


; imprimir nome
syscall
mov rax, 1
tam_nome equ 10 mov rdi, 1
; ler nome do usuário mov rsi, nome
mov rax, 0 mov rdx, tam_nome
section .bss syscall
mov rdi, 0
nome resb tam_nome
mov rsi, nome
; finalizar programa
mov rdx, tam_nome
section .text mov rax, 60
syscall mov rdi, 0
global _start syscall
NASM : Ola Ana.
section .data _start:
ola db "Ola " mov rax, 1
ana db "Ana." mov rdi, 1
mov rsi, ola
section .text mov rdx, 8
global _start syscall

mov rax, 60
mov rdi, 0
syscall
NASM : Sub-rotinas
• Funções
• call e ret
• O código não se altera com a execução
NASM : Sub-rotinas
section .data _start: ; imprimir mensagem 2 ler_msg: encerrar:
msg1 db "Digite seu ; imprimir mensagem 1 mov rsi, msg2 mov rax, 0 mov rax, 60
nome: ", 10
mov rsi, msg1 mov rdx, tam2 mov rdi, 0 mov rdi, 0
tam1 equ $-msg1
mov rdx, tam1 call imprimir_msg syscall syscall
msg2 db "Ola, "
call imprimir_msg ret ret
tam2 equ $-msg2
; imprimir nome
tam_nome equ 10
; ler nome do usuário mov rsi, nome imprimir_msg:
mov rsi, nome mov rdx, tam_nome mov rax, 1
section .bss
mov rdx, tam_nome call imprimir_msg mov rdi, 1
nome resb tam_nome
call ler_msg syscall
call encerrar ret
section .text
global _start
section .data
msg db "Hello world!", LF, NULL
segment .data tam equ $-msg

segment .data section .text


LF equ 10 ; Line Feed global _start
NULL equ 0ah ; Final da String
SYS_EXIT equ 60 ; Codigo de chamada _start:
para finalizar mov rax, SYS_WRITE
RET_EXIT equ 0 ; Operacao com Sucesso mov rdi, STD_OUT
STD_IN equ 00 ; Entrada padrao mov rsi, msg
STD_OUT equ 1 ; Saida padrao mov rdx, tam
SYS_READ equ 0 ; Operacao de Leitura syscall
SYS_WRITE equ 1 ; Operacao de Escrita mov rax, SYS_EXIT
mov rdi, RET_EXIT
syscall
Constantes (.data)
Variáveis (.bss (Block Starting Symbol))
Comparar Valores
• Assembly realiza comparações com 2 comandos, um deles
normalmente é o comando CMP (outros fazem esse mesmo
serviço) que possui a sintaxe:
• $ cmp registrador1, registrador2
Comparando maior que
section .data
x dd 10
y dd 50

msg1 db ’X maior que Y’, LF, NULL


tam1 equ $ - msg1
msg2 db ’Y maior que X’, LF, NULL
tam2 equ $ - msg2
Comparando maior que
section .text jg maior
global _start mov rsi, msg2 mov rax, 1
mov rdx, tam2 mov rdi, 1
_start: jmp senao syscall
mov r8, QWORD [x] maior:
mov r9, QWORD [y] mov rsi, msg1 mov rax, 60
mov rdx, tam1 mov rdi, 0
cmp r8, r9 senao: syscall
Comparar Valores
Linguagem de alto nível Linguagem de baixo nível

Esses saltos são


chamados de
"condicionais", ou
seja, dependem que
uma comparação
ocorra. Porém ainda
existe o comando JMP
que é um salto
"incondicional", isso é,
não depende que
nada ocorra.
Principais Operações do NASM
• Load/Store: mov
• Lógicas: xor,and,or
• Aritméticos: add,sub,inc,dec
• Comparativas: cmp,test
• Saltos: je,jne,jz,jnz,jmp
• Pilha: push,pop
• Interrupção: int
Instrução: MOV
• Copie o conteúdo de um registro/memória para outro ou altere o
valor de uma variável de registro/memória para um valor imediato.
• Exemplo: mov dest, src
• src deve ser um registrador/operando de memória
• src e dest não podem ser operandos de memória juntos.
Instrução: ADD
• Usado para adicionar os valores de duas variáveis reg/memória e
armazenar o resultado no primeiro operando.
• Exemplo: add dest, src || dest = dest + src;
• src deve ser um registrador/operando de memória
• src e dest não podem ser operandos de memória juntos.
• ambos os operandos devem ter o mesmo tamanho.
Instrução: SUB
• Usado para subtrair os valores de duas variáveis reg/memória e
armazenar o resultado no primeiro operando.
• Exemplo: sub dest, src || dest = dest - src;
• src deve ser um registrador/operando de memória
• src e dest não podem ser operandos de memória juntos.
• ambos os operandos devem ter o mesmo tamanho.
Instrução: INC e DEC
• INC: Usado para incrementar o valor de uma variável
reg/memória em 1
• Exemplo: INC eax ; eax++ || INC byte[var]

• DEC: Usado para diminuir o valor de uma variável reg/memória


em 1
• Exemplo: DEC eax ; eax-- || DEC byte[var]
Instrução: MUL
• Usado para multiplicar o valor de uma variável reg/memória com o reg
RAX / EAX / AX / AL.
• Exemplo: mul src
• O MUL funciona de acordo com as seguintes regras:
• Se src for 1 byte, então AX = AL * src
• Se src for 1 palavra (2 bytes), então DX:AX = AX * src (ou seja, os 16 bits
superiores do resultado irão para DX e os 16 bits inferiores irão para AX)
• Se src tiver 2 palavras (32 bits), então EDX:EAX = EAX * src (ou seja, os 32 bits
superiores do resultado irão para EDX e os 32 bits inferiores irão para EAX)
• Se src tiver 4 palavras (64 bits), então RDX:RAX = RAX * src (ou seja, os 64 bits
superiores do resultado irão para RDX e os 64 bits inferiores irão para RAX)
Instrução: IMUL
• A instrução IMUL funciona com a multiplicação de números
assinados. Pode ser usada principalmente em três formas
diferentes.
a. imul src
b. imul dest, src
c. imul dest, src1, src2

• Se usarmos imul como em (a), então seu funcionamento segue as


mesmas regras de MUL
• Se usarmos isso na forma (b), então dest = dest * src
• Se usarmos isso na forma (c), então dest = src1 * scr2
Instrução: DIV
• Usado para dividir o valor de RDX:RAX / EDX:EAX / DX:AX / AX reg
com reg / variável de memória.
• Exemplo: div src
• DIV funciona de acordo com as seguintes regras.
• If src is 1 byte then AX will be divide by src, remainder will go to AH and
quotient will go to AL.
• If src is 1 word (2 bytes) then DX:AX will be divide by src, remainder will go
to DX and quotient will go to AX
• If src is 2 words long(32 bit) then EDX:EAX will be divide by src, remainder
will go to EDX and quotient will go to EAX
• If src is 4 words long(64 bit) then RDX:RAX will be divide by src, remainder
will go to RDX and quotient will go to RAX
Instrução: NEG
• A instrução NEG nega uma determinada variável reg/memória.
• Exemplo: neg op1
Instrução: SHL e SHR (Shift)
• O Shift movimenta a cadeia binaria para o lado direito (shr) ou
esquerdo (shl).
• Exemplo: shr op1, [quantidades de bits que serão movidos]
Instrução: AND, OR, NOT, XOR
• AND: Executa AND lógico bit a bit de op1 e op2, atribuindo o resultado
a op1.
• Exemplo: and op1, op1
• OR: Executa OR lógico bit a bit de op1 e op2, atribuindo o resultado a
op1.
• Exemplo: or op1, op1
• NOT: Executa NOT lógico bit a bit de op1 e atribui o resultado a op1.
• Exemplo: not op1
• XOR: Executa XOR lógico bit a bit de op1 e op2, atribuindo o resultado
a op1.
• Exemplo: xor op1, op2
_start:
mov r8, QWORD[inicio] mov rax, SYS_EXIT

LOOP FOR mov r9, QWORD[fim]


mov rdi, RET_EXIT
syscall
section .data repetir:
cmp r8, r9
inicio dq 0 jge fim_loop
mov rax, r8
fim dq 10 mov rsi, numero
section .bss call int_to_string
syscall
numero resb 1
section .text mov rax, SYS_WRITE
mov rdi, STD_OUT
global _start mov rdx, 7
syscall

; adicionar a sub inc r8


rotina int_to_string jmp repetir
fim_loop:
Converter Inteiro para String
section .data int_to_string: _start:
mov rbx, 10 mov r8, 0x0
lf db LF prox_digito: mov rax, 34 ; é preciso atribuir o valor em rax
inc r8 mov rsi, numero ; array de char
mov rdx, 0 call int_to_string
section .bss div rbx
numero resq 1 add dl, '0' mov rax, sys_write
dec rsi mov rdi, std_out
mov [rsi], dl mov rdx, r8
section .text cmp rax, 0 syscall
global _start jnz prox_digito
ret mov rax, sis_exit
mov rdi, ret_exit
syscall
Converter String para Inteiro
section .data string_to_int: _start: mov rsi, numero
mov rax, 0
lf db LF prox_digit: mov rax, 0 call int_to_string
tam_val equ mov dl, byte[rsi] mov rdi, 0
2 inc rsi
mov rsi, val mov rax, 1
cmp dl, 48
jl fim mov rdx, tam_val mov rdi, 1
section .bss cmp dl, 57 syscall mov rdx, 3
numero resq jg fim
syscall
1 sub dl, 48
imul rax, 10 call string_to_int
val resb 2 add rax, rdx mov rax, sis_exit
jmp prox_digit
fim: inc rax mov rdi, ret_exit
section .text
ret syscall
global _start

Você também pode gostar