Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
bits 32
mov ah, bh
mov eax, ebx$ nasm tst.asm -o tstbits 32
mov eax, 0x11223344$ nasm tst.asm -o tst
$ ndisasm -b32 tst
$ ndisasm -b16 tstB8 44 33mov eax, [rbx] ; Lê do endereço DS:RBX
mov eax, [rbp] ; Lê do endereço SS:RBPbits 64
default rel
section .rodata
msg: db "Hello World!", 0
section .text
global assembly
assembly:
lea rax, [msg]
ret#include <stdio.h>
char *assembly(void);
int main(void)
{
printf("Resultado: %s\n", assembly());
return 0;
}mov rax, [rel my_var]$ nasm assembly.asm -o assembly.o -felf64
$ gcc main.c -c -o main.o
$ gcc *.o -o testfuncao:
call __x86.get_pc_thunk.bx
add ebx, 12345 ; Soma EBX com o endereço relativo 12345
; ...
__x86.get_pc_thunk.bx:
mov ebx, [esp]
retEntendendo as instruções condicionais e as status flags.
Registrador EFLAGS e FLAGS.
cmp rax, rbx
jnz nao_igual ; Salta se RAX e RBX não forem iguaisstc ; (Set CF) Seta o valor da Carry Flag
clc ; (Clear CF) Zera o valor da Carry Flag
cmc ; (coMplement CF) Inverte o valor da Carry Flagstd ; (Set DF) Seta o valor da Direction Flag
cld ; (Clear DF) Zera o valor da Direction Flagsti ; (Set IF) Seta o valor da Interrupt Flag
cli ; (Clear IF) Zera o valor da Interrupt Flag// Em 16-bit
struct elem {
uint16_t offset;
uint16_t segment;
}
struct elem idt[256];bits 16
org 0x100
VADDR equ 0xb800
; ID, segmento, offset
%macro setint 3
mov bx, (%1) * 4
mov word [es:bx], %3
mov word [es:bx + 2], %2
%endmacro
; -- Main -- ;
mov ax, 0
mov es, ax
setint 0x66, cs, int_putchar
mov al, 'A'
mov ah, 0x0B
int 0x66
mov ah, 0x0C
int 0x66
ret
; -- Interrupção -- ;
int_cursor: dw 0
; Argumentos:
; AL Caractere
; AH Atributo
int_putchar:
push es
mov bx, VADDR
mov es, bx
mov di, [int_cursor]
mov word [es:di], ax
add word [int_cursor], 2
pop es
iret$ nasm int.asm -o int.com
$ dosbox int.combits 16
org 0x100
; ID, segmento, offset
%macro setint 3
mov bx, (%1) * 4
mov word [es:bx], %3
mov word [es:bx + 2], %2
%endmacro
; -- Main -- ;
xor ax, ax
mov es, ax
setint 0x03, cs, break
int3
int3
ret
; -- Breakpoint -- ;
break:
mov ah, 0x0E
mov al, 'X'
int 0x10
iret#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <signal.h>
void segfault(int signum)
{
fputs("Tá pegando fogo bixo!\n", stderr);
exit(signum);
}
// Esse código também funciona no Windows.
int main(void)
{
char *desastre = NULL;
struct sigaction action = {
.sa_handler = segfault,
};
sigaction(SIGSEGV, &action, NULL);
strcpy(desastre, "Eita!");
puts("Tchau mundo!");
return 0;
}bits 64
default rel
section .rodata align=16
sum_array: dd 1.5
dd 2.5
dd 3.5
dd 4.5
section .text
global assembly
assembly:
movaps xmm0, [rdi]
addps xmm0, [sum_array]
movaps [rdi], xmm0
ret#include <stdio.h>
void assembly(float *array);
int main(void)
{
float array[4] = {5.0f, 5.0f, 5.0f, 5.0f};
assembly(array);
printf("Resultado: %f, %f, %f, %f\n", array[0],
return 0;
}

Convertendo valores entre float, double e inteiro.
#include <stdio.h>
float sum(float x, float y);
int main(void)
{
printf("Resultado: %f\n", sum(5.0f, 1.5f));
return 0;
}bits 64
section .text
global sum
sum:
addss xmm0, xmm1
ret#include <stdio.h>
double my_sqrt(double x);
int main(void)
{
printf("Resultado: %f\n", my_sqrt(81.0));
return 0;
}bits 64
section .text
global my_sqrt
my_sqrt:
sqrtsd xmm0, xmm0
retADDPS xmm(n), xmm(n)
ADDPS xmm(n), float(4)
ADDPD xmm(n), xmm(n)
ADDPD xmm(n), double(2)SUBPS xmm(n), xmm(n)
SUBPS xmm(n), float(4)
SUBPD xmm(n), xmm(n)
SUBPD xmm(n), double(2)ADDSS xmm(n), xmm(n)
ADDSS xmm(n), float(1)
ADDSD xmm(n), xmm(n)
ADDSD xmm(n), double(1)SUBSS xmm(n), xmm(n)
SUBSS xmm(n), float(1)
SUBSD xmm(n), xmm(n)
SUBSD xmm(n), double(1)MULPS xmm(n), xmm(n)
MULPS xmm(n), float(4)
MULPD xmm(n), xmm(n)
MULPD xmm(n), double(2)MULSS xmm(n), xmm(n)
MULSS xmm(n), float(1)
MULSD xmm(n), xmm(n)
MULSD xmm(n), double(1)DIVPS xmm(n), xmm(n)
DIVPS xmm(n), float(4)
DIVPD xmm(n), xmm(n)
DIVPD xmm(n), double(2)DIVSS xmm(n), xmm(n)
DIVSS xmm(n), float(1)
DIVSD xmm(n), xmm(n)
DIVSD xmm(n), double(1)RCPPS xmm(n), xmm(n)
RCPPS xmm(n), float(4)RCPSS xmm(n), xmm(n)
RCPSS xmm(n), float(1)SQRTPS xmm(n), xmm(n)
SQRTPS xmm(n), float(4)
SQRTPD xmm(n), xmm(n)
SQRTPD xmm(n), double(2)SQRTSS xmm(n), xmm(n)
SQRTSS xmm(n), float(1)
SQRTSD xmm(n), xmm(n)
SQRTSD xmm(n), double(1)RSQRTPS xmm(n), xmm(n)
RSQRTPS xmm(n), float(4)RSQRTSS xmm(n), xmm(n)
RSQRTSS xmm(n), float(1)MAXPS xmm(n), xmm(n)
MAXPS xmm(n), float(4)
MAXPD xmm(n), xmm(n)
MAXPD xmm(n), double(2)MAXSS xmm(n), xmm(n)
MAXSS xmm(n), float(1)
MAXSD xmm(n), xmm(n)
MAXSD xmm(n), double(1)MINPS xmm(n), xmm(n)
MINPS xmm(n), float(4)
MINPD xmm(n), xmm(n)
MINPD xmm(n), double(2)MINSS xmm(n), xmm(n)
MINSS xmm(n), float(1)
MINSD xmm(n), xmm(n)
MINSD xmm(n), double(1)



CVTPS2PD xmm(n), xmm(n)
CVTPS2PD xmm(n), float(2)CVTPD2PS xmm(n), xmm(n)
CVTPD2PS xmm(n), double(2)CVTSS2SD xmm(n), xmm(n)
CVTSS2SD xmm(n), float(1)CVTSD2SS xmm(n), xmm(n)
CVTSD2SS xmm(n), double(1)CVTPD2DQ xmm(n), xmm(n)
CVTPD2DQ xmm(n), double(2)
CVTTPD2DQ xmm(n), xmm(n)
CVTTPD2DQ xmm(n), double(2)CVTDQ2PD xmm(n), xmm(n)
CVTDQ2PD xmm(n), dword(2)CVTSD2SI reg32/64, xmm(n)
CVTSD2SI reg32/64, double(1)
CVTTSD2SI reg32/64, xmm(n)
CVTTSD2SI reg32/64, double(1)CVTSI2SD xmm(n), reg32/64
CVTSI2SD xmm(n), dword(1)
CVTSI2SD xmm(n), qword(1)CVTPS2DQ xmm(n), xmm(n)
CVTPS2DQ xmm(n), float(4)
CVTTPS2DQ xmm(n), xmm(n)
CVTTPS2DQ xmm(n), float(4)CVTDQ2PS xmm(n), xmm(n)
CVTDQ2PS xmm(n), dword(4)CVTSS2SI reg32/64, xmm(n)
CVTSS2SI reg32/64, float(1)
CVTTSS2SI reg32/64, xmm(n)
CVTTSS2SI reg32/64, float(1)CVTSI2SS xmm(n), reg32/64
CVTSI2SS xmm(n), dword(1)
CVTSI2SS xmm(n), qword(1)




mov [0x100], ax; O nome deste recurso é "segment override"
; Ou em PT-BR: Substituição do segmento
mov [es:0x100], ax
; OU alternativamente:
es mov [0x100], axendereço_físico = (segmento << 4) + deslocamentoorg endereço_inicialbits 16
org 0x100
msg: db "abc"
codigo:
mov ax, 77
retbits 16
org 0x100
mov ah, 0x0E
mov al, 'H'
int 0x10
mov al, 'i'
int 0x10
ret$ nasm hello.asm -o hello.com$ sudo apt install gcc-multilib$ gcc hello.c -o hello -m32$ ndisasm -b32 binaryAprendendo a usar o x87 para fazer cálculos.
Listando algumas instruções de movimentação de dados do SSE.
MOVAPS xmm(n), xmm(n)
MOVAPS xmm(n), float(4)
MOVAPS float(4), xmm(n)
MOVUPS xmm(n), xmm(n)
MOVUPS xmm(n), float(4)
MOVUPS float(4), xmm(n)
MOVAPD xmm(n), xmm(n)
MOVAPD xmm(n), double(2)
MOVAPD double(2), xmm(n)
MOVUPD xmm(n), xmm(n)
MOVUPD xmm(n), double(2)
MOVUPD double(2), xmm(n)PAVGB xmm(n), xmm(n)
PAVGB xmm(n), ubyte(16)
PAVGW xmm(n), xmm(n)
PAVGW xmm(n), uword(8)ANDPS xmm(n), xmm(n)
ANDPS xmm(n), float(4)
ANDPD xmm(n), xmm(n)
ANDPD xmm(n), double(2)st0 = 10
st1 = 20
st2 = 30
* é feito um push do valor 40
st0 = 40
st1 = 10
st2 = 20
st3 = 30
* é feito um pop, o valor 40 é pego.
st0 = 10
st1 = 20
st2 = 30mov eax, st1finitfld mem32fp
fld mem64fp
fld mem80fp
fld st(i)
fild mem16int
fild mem32int
fild mem64intfst mem32fp
fst mem64fp
fst st(i)
fstp mem32fp
fstp mem64fp
fstp mem80fp
fstp st(i)fist mem16int
fist mem32int
fistp mem16int
fistp mem32int
fistp mem64intbits 64
section .data
num: dq 23.87
section .bss
result: resd 1
section .text
global assembly
assembly:
finit
fld qword [num]
fistp dword [result]
mov eax, [result]
ret#include <stdio.h>
int assembly(void);
int main(void)
{
printf("Resultado: %d\n", assembly());
return 0;
}fadd mem32fp
fadd mem64fp
fadd st(0), st(i)
fadd st(i), st(0)
faddp st(i), st(0)
faddp
fiadd mem16int
fiadd mem32intbits 64
section .data
num1: dq 24.3
num2: dq 0.7
section .bss
result: resd 1
section .text
global assembly
assembly:
finit
fld qword [num1]
fadd qword [num2]
fist dword [result]
mov eax, [result]
ret#include <stdio.h>
int assembly(void);
int main(void)
{
printf("Resultado: %d\n", assembly());
return 0;
}fsub mem32fp
fsub mem64fp
fsub st(0), st(i)
fsub st(i), st(0)
fsubp st(i), st(0)
fsubp
fisub mem16int
fisub mem32intfdiv mem32fp
fdiv mem64fp
fdiv st(0), st(i)
fdiv st(i), st(0)
fdivp st(i), st(0)
fdivp
fidiv mem16int
fidiv mem32intfmul mem32fp
fmul mem64fp
fmul st(0), st(i)
fmul st(i), st(0)
fmulp st(i), st(0)
fmulp
fimul mem16int
fimul mem32inta = a - b // fsub etc.
a = b - a // fsubr etc.fxch st(i)
fxchfsqrtfabsfchsfcosfsinfsincosfptanfpatanf2xm1fyl2xfyl2xp1frndintfprem
fprem1fcomi st(0), st(i)
fcomip st(0), st(i)
fucomi st(0), st(i)
fucomip st(0), st(i)fcmovb st(0), st(i)
fcmove st(0), st(i)
fcmovbe st(0), st(i)
fcmovu st(0), st(i)
fcmovnb st(0), st(i)
fcmovne st(0), st(i)
fcmovnbe st(0), st(i)
fcmovnu st(0), st(i)bits 64
section .data
num1: dq 3.0
num2: dq 3.0
section .bss
result: resd 1
section .text
global assembly
assembly:
finit
fld qword [num1]
fmul qword [num2]
fst dword [result]
movss xmm0, [result]
ret#include <stdio.h>
float assembly(void);
int main(void)
{
printf("Resultado: %f\n", assembly());
return 0;
}#include <stdio.h>
void assembly(float *array);
int main(void)
{
float array[4];
assembly(array);
printf("%f, %f, %f, %f\n", array[0], array[1], array[2], array[3]);
return 0;
}bits 64
default rel
section .rodata align=16
local_array: dd 1.23
dd 2.45
dd 3.67
dd 4.89
section .text
global assembly
assembly:
movaps xmm5, [local_array]
movaps [rdi], xmm5
ret
#include <stdio.h>
void assembly(char *array);
int main(void)
{
char text[16];
assembly(text);
printf("Resultado: %s\n", text);
return 0;
}bits 64
default rel
section .rodata
string: db "Hello World!", 0, 0, 0, 0
section .text
global assembly
assembly:
movups xmm0, [string]
movups [rdi], xmm0
retMOVSS xmm(n), xmm(n)
MOVSS xmm(n), float(1)
MOVSS float(1), xmm(n)
MOVSD xmm(n), xmm(n)
MOVSD xmm(n), double(1)
MOVSD double(1), xmm(n)MOVLPS xmm(n), float(2)
MOVLPS float(2), xmm(n)
MOVLPD xmm(n), double(1)
MOVLPD double(1), xmm(n)MOVHPS xmm(n), float(2)
MOVHPS float(2), xmm(n)
MOVHPD xmm(n), double(1)
MOVHPD double(1), xmm(n)MOVLHPS xmm(n), xmm(n)MOVHLPS xmm(n), xmm(n)MOVMSKPS reg32/64, xmm(n)
MOVMSKPD reg32/64, xmm(n)PEXTRW reg32/64, xmm(n), imm8
PEXTRW uword(1), xmm(n), imm8 ; Adicionado no SSE4PINSRW xmm(n), reg32, imm8
PINSRW xmm(n), uword(1), imm8PMAXUB xmm(n), xmm(n)
PMAXUB xmm(n), ubyte(16)
PMAXUW xmm(n), xmm(n) ; Adicionado no SSE4
PMAXUW xmm(n), uword(8) ; Adicionado no SSE4PMINUB xmm(n), xmm(n)
PMINUB xmm(n), ubyte(16)
PMINUW xmm(n), xmm(n) ; Adicionado no SSE4
PMINUW xmm(n), uword(8) ; Adicionado no SSE4PMAXSB xmm(n), xmm(n) ; Adicionado no SSE4
PMAXSB xmm(n), byte(16) ; Adicionado no SSE4
PMAXSW xmm(n), xmm(n)
PMAXSW xmm(n), word(8)
PMAXSD xmm(n), xmm(n) ; Adicionado no SSE4
PMAXSD xmm(n), dword(4) ; Adicionado no SSE4PMINSB xmm(n), xmm(n) ; Adicionado no SSE4
PMINSB xmm(n), byte(16) ; Adicionado no SSE4
PMINSW xmm(n), xmm(n)
PMINSW xmm(n), word(8)PMOVMSKB reg32/64, xmm(n)PMULHW xmm(n), xmm(n)
PMULHW xmm(n), uword(8)
PMULHUW xmm(n), xmm(n)
PMULHUW xmm(n), uword(8)PSADBW xmm(n), xmm(n)
PSADBW xmm(n), ubyte(16)MOVDQA xmm(n), xmm(n)
MOVDQA xmm(n), qword(2)
MOVDQA qword(2), xmm(n)MOVDQU xmm(n), xmm(n)
MOVDQU xmm(n), qword(2)
MOVDQU qword(2), xmm(n)PADDB xmm(n), xmm(n)
PADDB xmm(n), byte(16)
PADDW xmm(n), xmm(n)
PADDW xmm(n), word(8)
PADDD xmm(n), xmm(n)
PADDD xmm(n), dword(4)
PADDQ xmm(n), xmm(n)
PADDQ xmm(n), qword(2)PSUBQ xmm(n), xmm(n)
PSUBQ xmm(n), qword(2)PMULUDQ xmm(n), xmm(n)
PMULUDQ xmm(n), dword(4)#include <stdio.h>
#include <inttypes.h>
void mularray(uint64_t *output, uint32_t *array);
int main(void)
{
uint32_t array[] = {3, 1, 2, 1};
uint64_t output[2];
mularray(output, array);
printf("Resultado: %" PRIu64 ", %" PRIu64 "\n", output[0], output[1]);
return 0;
}bits 64
default rel
section .rodata align=16
mul_values: dd 2, 3, 4, 5
section .text
global mularray
mularray:
movdqa xmm0, [mul_values]
pmuludq xmm0, [rsi]
movdqa [rdi], xmm0
retPSLLDQ xmm(n), imm8PSRLDQ xmm(n), imm8ANDNPS xmm(n), xmm(n)
ANDNPS xmm(n), float(4)
ANDNPD xmm(n), xmm(n)
ANDNPD xmm(n), double(2)ORPS xmm(n), xmm(n)
ORPS xmm(n), float(4)
ORPD xmm(n), xmm(n)
ORPD xmm(n), double(2)XORPS xmm(n), xmm(n)
XORPS xmm(n), float(4)
XORPD xmm(n), xmm(n)
XORPD xmm(n), double(2); As duas instruções abaixo são equivalentes.
CMPPS xmm1, xmm2, 0
CMPEQPS xmm1, xmm2CMPPS xmm(n), xmm(n), imm8
CMPPS xmm(n), float(4), imm8
CMPPD xmm(n), xmm(n), imm8
CMPPD xmm(n), double(2), imm8CMPSS xmm(n), xmm(n), imm8
CMPSS xmm(n), float(4), imm8
CMPSD xmm(n), xmm(n), imm8
CMPSD xmm(n), double(2), imm8COMISS xmm(n), xmm(n)
COMISS xmm(n), float(1)
UCOMISS xmm(n), xmm(n)
UCOMISS xmm(n), float(1)
COMISD xmm(n), xmm(n)
COMISD xmm(n), double(1)
UCOMISD xmm(n), xmm(n)
UCOMISD xmm(n), double(1)mov ah, 0x0E
mov al, 'H'
int 0x10
mov al, 'i'
int 0x10
retbits 16
org 0x100
mov si, string
call echo
ret
string: db "Hello World!", 0
; SI = ASCIIZ string
; BH = Página
echo:
mov ah, 0x0E
.loop:
lodsb
test al, al
jz .stop
int 0x10
jmp .loop
.stop:
retstr: db 'A', 0x05, 'B', 0x0C, 'C', 0x0A// Em modo de texto 80x25, padrão do MS-DOS
struct character {
uint8_t ascii;
uint8_t attribute;
};
struct character vmem[8][25][80];bits 16
org 0x100
%macro puts 2
mov bx, %1
mov bp, %2
call puts
%endmacro
puts 0x000A, str1
puts 0x000C, str2
ret
str1: db `Hello World!\r\n`, 0
str2: db "Second message.", 0
; BL = Atributo
; BH = Página
; BP = ASCIIZ String
puts:
mov ah, 0x03
int 0x10
mov di, bp
call strlen
mov cx, ax
mov al, 0b01
mov ah, 0x13
int 0x10
ret
; DI = ASCIIZ String
; Retorna o tamanho da string
strlen:
mov cx, -1
xor ax, ax
repnz scasb
mov ax, -2
sub ax, cx
retcall rel16/rel32Instruction_Pointer = Instruction_Pointer + operandbits 64
call $call r/mmov rax, rotulo
call raxcall seg16:off16 ; Em 16-bit
call seg16:off32 ; Em 32-bit
call mem16:16 ; Em 16-bit
call mem16:32 ; Em 32-bit
call mem16:64 ; Em 64-bitcall 0x1234:0xabcdef99call [rbx] ; Próximo e absoluto
call near [rbx] ; Próximo e absoluto
call far [rbx] ; Distante11 11 bb bb aa aabits 32
my_addr: dd 0xbbbb1111 ; Deslocamento
dw 0xaaaa ; Segmento
; E usada assim:
call far [my_addr]ret
retf
retn
ret imm16
retf imm16
retn imm16retf ; Usado em procedimentos que devem ser chamados com far callRIP = pop();
CS = pop();
RSP = RSP + 12;bits 16
mov ecx, 99999
.lp:
; Faça alguma coisa
a32 loop .lpbits 32
mov byte [es:ebx], 32
es mov byte [ebx], 32bits 32
inc ecx
db 0xFF, 0xC1inc reg
inc r/mbits 64
section .text
global my_strlen
my_strlen:
mov ecx, -1
xor eax, eax
repne scasb
mov eax, -2
sub eax, ecx
ret
#include <stdio.h>
int my_strlen(char *);
int main(void)
{
printf("Resultado: %d\n", my_strlen("Hello World!"));
return 0;
}




