diretórios 8 e 13 de exemplos

This commit is contained in:
Blau Araujo 2025-06-18 09:53:30 -03:00
parent 62338a8185
commit 6fbe5f3a62
13 changed files with 820 additions and 0 deletions

View file

@ -0,0 +1,76 @@
; ----------------------------------------------------------
str_to_int:
; ----------------------------------------------------------
; Converte string numérica com sinal em inteiro (int32_t).
; Entradas:
; RSI = Endereço da string (char *str)
; RDX = Endereço para estado de erro (int *err /* nullable */)
; Saída:
; RAX = valor convertido (int32_t)
; Sucesso: *rdx = 1
; Erro: *rdx = 0
; ----------------------------------------------------------
push rbx ; salva rbx
push rcx ; salva rcx
xor rcx, rcx ; rcx = 0 (sinal: 0 = positivo, 1 = negativo)
; ------------------------------------------------------
; Testa ponteiro nulo
; ------------------------------------------------------
test rsi, rsi
jz .error
; ------------------------------------------------------
; Verifica o sinal na string
; ------------------------------------------------------
mov bl, [rsi]
cmp bl, '-' ; caractere de sinal negativo?
jne .check_plus
inc rcx ; rcx = 1 => negativo
inc rsi ; avança o ponteiro
jmp .convert
stramoecheck_plus:
cmp bl, '+' ; caractere de sinal positivo?
jne .convert
inc rsi ; ignora '+'
.convert:
; ------------------------------------------------------
; Chama _str_to_uint
; ------------------------------------------------------
call _str_to_uint ; RSI = str, RDX = err, RAX = resultado (uint32_t)
; ------------------------------------------------------
; Verifica se _str_to_uint retornou erro
; ------------------------------------------------------
test rdx, rdx
jz .check_sign
cmp dword [rdx], 0
je .error
.check_sign:
test rcx, rcx ; se rcx = 1, é número negativo
jz .check_range_pos
; ------------------------------------------------------
; Verifica se valor cabe em int32_t negativo
; ------------------------------------------------------
cmp eax, 2147483648
ja .error ; menor que INT_MIN -> erro
neg eax ; aplica o sinal negativo
jmp .success
.check_range_pos:
; ------------------------------------------------------
; Verifica se valor cabe em int32_t positivo
; ------------------------------------------------------
cmp eax, 2147483647
ja .error ; maior que INT_MAX -> erro
.success:
test rdx, rdx
jz .done
mov dword [rdx], 1 ; *err = 1
jmp .done
.error:
xor eax, eax ; valor de erro = 0
test rdx, rdx
jz .done
mov dword [rdx], 0 ; *err = 0
.done:
pop rcx
pop rbx
ret

View file

@ -0,0 +1,193 @@
q
break main
run 23 19
p argv
p argv[1]
x /3bx argv[1]
x /1wx argv[2]
x /1dx argv[2]
x /1dx argv[1]
x /1gx argv[1]
x /5bx argv[1]
x /6bx argv[1]
x /7bx argv[1]
x /7bx argv
x /7bx argv[0]
x /7bx argv[1]
x /3bx argv[1]
x /3bx argv[2]
x /x argv[2]
x /x argv[1]
x /dx argv[1]
x /d2x argv[1]
x /1dx argv[1]
x /wx argv[1]
x /2wx argv[1]
x /3wx argv[1]
x /3bx argv[1]
x /3bx argv[2]
x /6bx argv[1]
x /6dx argv[1]
x /6wx argv[1]
q
break main
run 123 456
x /8bx argv[1]
x /8cx argv[1]
x /8bc argv[1]
x /8bx argv[1]
x /8bd argv[1]
x /8bx argv[1]
x /1gx argv[1]
x /1wx argv[1]
x /1wx argv[2]
x /1bx argv[1]
x /4bx argv[1]
x /4bx argv[2]
x /1wx argv[1]
x /1wx argv[2]
p (int)argv[1]
p (int)*argv[1]
p (int)*(argv[1])
p *((int)argv[1])
p argv[1]
q
break main
run
q
b main
r
p a
n
p a
p b
x /1wx a
x /1wx &a
x /1wx b
q
b main
r
n
x /1wx &a
x /1wx b
x /1wx &c
x /1wx d
x /4bx b
q
break printf
r
q
break main
run
n 4
x /1wx &a
x /1wx b
x /1wx &c
x /1wx d
x /1w d
x /1wd d
x /1wd &a
x /1wd b
x /1wd &c
x /1wd d
q
break main
run
next 3
x /1wx &a
x /1wx b
x /1wx c
x /4bx &a
x /4bx b
x /4bx c
q
b _start
layout regs
r
n
q
b _start
r
n
i registers rsi
x /1s &rsi
x /1s rsi
x /1s $rsi
x /1s num_str
x /1s &num_str
n
i registers rax
q
break _start
rr
r
info registers rax rdx
info registers rax rdx rsi
n
info registers rax rdx rsi
x /1s &num_str
x /1s &num
x /1wx &num
x /1wx &status
k
r
n 2
info registers rax rdx rsi
x /1wx &num
x /1wx &status
n
info registers rax rdx rsi
x /1wx &num
x /1wx &status
n
x /1wx &status
info registers rax rdx rsi
k
q
break _start
run
n 2
info registers rax rdx rsi
x /1w &num_str
x /1wx &num_str
x /1s &num
x /1wx &num
x /1wx &status
n
info registers rax rdx rsi
x /1wx &num
x /1wx &status
n
k
r
n2
n 2
info registers rax rdx rsi
x /1wx &num
x /1wx &status
q
b _start
r
n 4
x /1wx &status
x /1wx &num
info registers rax rdx rsi
q
break _start
run
n 2
info registers rax rdx rsi
x /1wx &num_str
x /1s &num_str
x /1wx &num_
x /1wx &num
x /1wx &status
n
n
info registers rax rdx rsi
x /1wx &num
x /1wx &status
print num
print &num
print (int)num
q

View file

@ -0,0 +1,14 @@
#include <stdio.h>
int main(void) {
int a = 123;
char *b = "123";
int *c = (int *)b; // Casting do valor no endereço 'b' para inteiro
printf("Inteiro a: %d\n", a);
printf("String b: %s\n", b);
printf("Inteiro c: %d\n", *c); // Imprime o valor no endereço 'c'
return 0;
}

View file

@ -0,0 +1,27 @@
#include <stdio.h>
#include <limits.h>
#include <float.h>
#include <locale.h>
int main(void) {
setlocale(LC_NUMERIC, "");
puts("Tipo Bytes Limites (x86_64)");
puts("========================================================================");
printf("char (%zu) %d a %d\n", sizeof(char), SCHAR_MIN, SCHAR_MAX);
printf("unsigned char (%zu) %d a %d\n", sizeof(unsigned char), 0, UCHAR_MAX);
printf("short (%zu) %'d a %'d\n", sizeof(short), SHRT_MIN, SHRT_MAX);
printf("unsigned short (%zu) %d a %'d\n", sizeof(unsigned short), 0, USHRT_MAX);
printf("int (%zu) %'d a %'d\n", sizeof(int), INT_MIN, INT_MAX);
printf("unsigned int (%zu) %d a %'u\n", sizeof(unsigned int), 0, UINT_MAX);
printf("long int (%zu) %'ld a %'ld\n", sizeof(long int), LONG_MIN, LONG_MAX);
printf("unsigned long int (%zu) %d a %'lu\n", sizeof(long unsigned int), 0, ULONG_MAX);
printf("long long (%zu) %'ld a %'ld\n", sizeof(long long int), LLONG_MIN, LLONG_MAX);
printf("unsigned long long (%zu) %d a %'llu\n", sizeof(unsigned long long int), 0, ULLONG_MAX);
printf("float (%zu) %.2E a %.2E\n", sizeof(float), FLT_MIN, FLT_MAX);
printf("double (%zu) %.2E a %.2E\n", sizeof(double), DBL_MIN, DBL_MAX);
printf("long double (%zu) %.2LE a %.2LE\n", sizeof(long double), LDBL_MIN, LDBL_MAX);
return 0;
}

View file

@ -0,0 +1,76 @@
; ----------------------------------------------------------
str_to_int:
; ----------------------------------------------------------
; Converte string numérica com sinal em inteiro (int32_t).
; Entradas:
; RSI = Endereço da string (char *str)
; RDX = Endereço para estado de erro (int *err /* nullable */)
; Saída:
; RAX = valor convertido (int32_t)
; Sucesso: *rdx = 1
; Erro: *rdx = 0
; ----------------------------------------------------------
push rbx ; salva rbx
push rcx ; salva rcx
xor rcx, rcx ; rcx = 0 (sinal: 0 = positivo, 1 = negativo)
; ------------------------------------------------------
; Testa ponteiro nulo
; ------------------------------------------------------
test rsi, rsi
jz .error
; ------------------------------------------------------
; Verifica o sinal na string
; ------------------------------------------------------
mov bl, [rsi]
cmp bl, '-' ; caractere de sinal negativo?
jne .check_plus
inc rcx ; rcx = 1 => negativo
inc rsi ; avança o ponteiro
jmp .convert
.check_plus:
cmp bl, '+' ; caractere de sinal positivo?
jne .convert
inc rsi ; ignora '+'
.convert:
; ------------------------------------------------------
; Chama _str_to_uint
; ------------------------------------------------------
call _str_to_uint ; RSI = str, RDX = err, RAX = resultado (uint32_t)
; ------------------------------------------------------
; Verifica se _str_to_uint retornou erro
; ------------------------------------------------------
test rdx, rdx
jz .check_sign
cmp dword [rdx], 0
je .error
.check_sign:
test rcx, rcx ; se rcx = 1, é número negativo
jz .check_range_pos
; ------------------------------------------------------
; Verifica se valor cabe em int32_t negativo
; ------------------------------------------------------
cmp eax, 2147483648
ja .error ; menor que INT_MIN -> erro
neg eax ; aplica o sinal negativo
jmp .success
.check_range_pos:
; ------------------------------------------------------
; Verifica se valor cabe em int32_t positivo
; ------------------------------------------------------
cmp eax, 2147483647
ja .error ; maior que INT_MAX -> erro
.success:
test rdx, rdx
jz .done
mov dword [rdx], 1 ; *err = 1
jmp .done
.error:
xor eax, eax ; valor de erro = 0
test rdx, rdx
jz .done
mov dword [rdx], 0 ; *err = 0
.done:
pop rcx
pop rbx
ret

129
curso/exemplos/08/uint.asm Normal file
View file

@ -0,0 +1,129 @@
; ----------------------------------------------------------
; Arquivo : uint.asm
; Montagem: nasm -g -f elf64 uint.asm
; Ligação : ls uint.o -o uint
; ----------------------------------------------------------
section .data
; ----------------------------------------------------------
num_str db "123", 0 ; string numérica
; ----------------------------------------------------------
section .bss
; ----------------------------------------------------------
num resd 1 ; 4 bytes para o valor UINT32
status resd 1 ; 4 bytes para o estado de término
; ----------------------------------------------------------
section .text
global _start
; ----------------------------------------------------------
_start:
; ----------------------------------------------------------
; Teste de chamada (verificar com o GDB)...
; ----------------------------------------------------------
mov rsi, num_str ; copia endereço da string em rsi
mov rdx, status ; copia o endereço do estado de erro em rdx
call _str_to_uint ; chama a sub-rotina de conversão
mov dword [num], eax ; copia o resultado como int para [num]
; ----------------------------------------------------------
_exit:
; ----------------------------------------------------------
mov rax, 60
mov rdi, 0
syscall
; ----------------------------------------------------------
; Sub-rotinas...
; ----------------------------------------------------------
_str_to_uint:
; ----------------------------------------------------------
; Converte string numérica em inteiro sem sinal (uint32_t).
; Entradas:
; RSI = Endereço da string (char *str)
; RDX = Endereço para estado de erro (int *err /* nullable */)
; Saída:
; RAX = valor convertido (uint32_t) ou 0, no caso de erro
; Sucesso: *rdx = 1
; Erro: *rdx = 0
; ----------------------------------------------------------
; Definição condicional do estado inicial de erro...
; ------------------------------------------------------
test rdx, rdx ; Se *err = NULL, rdx = 0
jz .skip_error ; Se for 0, pula a definição do erro
mov dword [rdx], 0 ; *err = 0 => estado inicial é de erro (falso)
; ------------------------------------------------------
.skip_error:
; ------------------------------------------------------
; Teste de ponteiro nulo...
; ------------------------------------------------------
test rsi, rsi ; verifica se enderçeo é nulo (0)
jz .error ; se for, termina retornando -1 (erro)
; ------------------------------------------------------
; Preparação...
; ------------------------------------------------------
push rbx ; salva rbx na pilha
xor rax, rax ; rax = 0 (acumula o resultado)
xor rbx, rbx ; rbx = 0 (recebe os caracteres no loop)
mov bl, [rsi] ; lê o primeiro byte
; ------------------------------------------------------
; Validação do primeiro byte...
; ------------------------------------------------------
cmp bl, 0x30 ; compara com menor byte válido
jl .error ; se menor, termina retornando -1
cmp bl, 0x39 ; compara com maior byte válido
jg .error ; se maior, termina retornando -1
.conv_loop:
; ------------------------------------------------------
; Condições de término da conversão ...
; ------------------------------------------------------
test bl, bl ; verifica se o byte é o terminador 0x00
je .success ; se for, termina com sucesso
cmp bl, 0x30 ; compara o byte em rbx com o menor dígito
jl .success ; se for menor, termina com sucesso
cmp bl, 0x39 ; compara o byte em rbx com o maior dígito
jg .success ; se for maior, termina com sucesso
; ------------------------------------------------------
; Conversão do dígito corrente...
; ------------------------------------------------------
sub rbx, 0x30 ; converte o dígito para seu valor numérico
; ------------------------------------------------------
; Limite válido: conv < (UINT_MAX - dígito) / 10
; ------------------------------------------------------
mov r8, rax ; Salva parcial da conversão em r8
mov r10, rdx ; Salva ponteiro de erro em r10
mov eax, -1 ; eax = 0xffffffff (UINT_MAX - 32 bits)
sub eax, ebx ; rax = UINT_MAX - dígito (dividendo)
xor rdx, rdx ; prepara rdx para receber o resto da divisão
mov r9, 10 ; divisor
div r9 ; limite(rax) = (UINT_MAX - dígito) / 10
cmp r8, rax ; se parcial > limite, teremos um estouro
jg .error ; se maior, termina com erro
mov rdx, r10 ; restaura rdx (pontiero para erros)
mov rax, r8 ; restaura rax (parcial da conversão)
; ------------------------------------------------------
; Processa a parcial da conversão...
; ------------------------------------------------------
imul rax, rax, 10 ; rax *= 10 (deslocamento do peso posicional)
add rax, rbx ; rax += novo algarismo
inc rsi ; avança para o próximo byte
mov bl, [rsi] ; carrega o dígito corrente em rbx
jmp .conv_loop
; ------------------------------------------------------
.error:
; ------------------------------------------------------
xor rax, rax ; Retorna 0 em caso de erro
jmp .done
; ------------------------------------------------------
.success:
; ------------------------------------------------------
; Redefinição condicional do estado final de sucesso...
; ------------------------------------------------------
test rdx, rdx ; Se *err = NULL, rdx = 0
jz .done ; Se for 0, pula a definição de sucesso
mov dword [rdx], 1 ; *err = 1 => estado final é de sucesso (verdadeiro)
; ------------------------------------------------------
.done:
; ------------------------------------------------------
pop rbx ; Restaura rbx
ret

51
curso/exemplos/08/uint.c Normal file
View file

@ -0,0 +1,51 @@
/*
* Arquivo : uint.c
* Compilação: gcc -Wall uint.c -o uintc
*/
#include <stdio.h>
#include <limits.h> // Requerido para obter UINT_MAX da plataforma
unsigned int str_to_uint(char *str, int *err /* nullable */);
int main(int argc, char **argv) {
if (argc == 1) {
fprintf(stderr, "Uso: %s NÚMERO\n", argv[0]);
return 1;
}
int status;
unsigned int num = str_to_uint(argv[1], &status);
if (status) {
printf("String: %s\nNúmero: %u\n", argv[1], num);
} else {
fprintf(stderr, "Erro de conversão!\n");
return 1;
}
return 0;
}
unsigned int str_to_uint(char *str, int *err /* nullable */) {
if (err) *err = 0; // Estado padrão é de erro (0 = falso)!
// Termina com erro e valor 0 se str==NULL ou se '0'>str[0]>'9'...
if (str == NULL || str[0] < '0' || str[0] > '9') return 0;
int dig; // Recebe o dígito convertido
unsigned int conv = 0; // Recebe a parcial da conversão
for (int i = 0; str[i] != '\0'; i++) {
// Se o caractere não for um dígito, termina a conversão...
if (str[i] < '0' || str[i] > '9') break;
// Converte o dígito corrente...
dig = str[i] - '0';
// Termina com erro e valor 0 se a próxima conversão exceder UINT_MAX...
if (conv > (UINT_MAX - dig) / 10) return 0;
// Processa a parcial da conversão...
conv = (conv * 10) + dig;
}
if (err) *err = 1; // Altera estado para sucesso (1 = verdadeiro)
return conv;
}

View file

@ -0,0 +1,107 @@
dir
l
l
b 70
r
i proc
q
b _start
r
n
x /1gx pipe_fds
x /1gx &pipe_fds
k
b 46
r
c
x /1gx &pipe_fds
n
n
k
q
b clone
r
x /1dx pipe_fds
x /1dx &pipe_fds
x /1dx &pipe_fds+8
x /1dx &pipe_fds + 8
x /1dx &(pipe_fds + 8 )
x /2dx &pipe_fds
i registers r13 r14
q
b clone
r
i registers r13 r14
q
b clone
r
i registers r13 r14
q
b clone
r
i registers r13 r14
q
b clone
r
i registers r13 r14
x /1dx &read_end
x /1dx &write_end
q
b _start.parada
r
q
b _start.parada
r
x /1dx &write_end
x /1dx &read_end
q
b _start.parada
r
k
q
b _start.parada
r
k
q
b _start.parada
r
c
q
b _start.parada
r
k
q
b _start.parada
r
c
q
b _start.parada1
b _start.parada2
r
x /1gx &read_end
x /1dx &read_end
x /1dx &write_end
x /1x &read_end
x /1dx &read_end
p read_end
p (int *)read_end
x /4bx &read_end
x /1bx &read_end
x /1bx &write_end
x /1wx &write_end
x /1wx &read_end
x /1gx &read_end
c
c
b _start.parada1
b _start.parada2
r
x /1wx &read_end
x /1wx &write_end
x /1gx &read_end
x /1wx &read_end
x /1wx &write_end
i proc
c
c
q

View file

@ -0,0 +1 @@
Salve, simpatia!

146
curso/exemplos/13/teste.asm Normal file
View file

@ -0,0 +1,146 @@
; Arquivo: pipe_ls_cat.asm
; Montar com: nasm -felf64 pipe_ls_cat.asm && ld -o pipe_ls_cat pipe_ls_cat.o
%define SYS_READ 0
%define SYS_WRITE 1
%define SYS_CLOSE 3
%define SYS_PIPE 22
%define SYS_DUP2 33
%define SYS_FORK 57
%define SYS_EXECVE 59
%define SYS_EXIT 60
%define SYS_WAITPID 61
%define STDIN_FD 0
%define STDOUT_FD 1
%define STDERR_FD 2
%define EXIT_SUCCESS 0
%define EXIT_FAILURE 1
section .rodata
cmd_ls db "/bin/ls", 0
arg0_ls dq cmd_ls
arg1_ls db "-l", 0
arg2_ls db "/proc/self/fd", 0
argv_ls dq arg0_ls, arg1_ls, arg2_ls, 0
cmd_cat db "/bin/cat", 0
arg0_cat dq cmd_cat
argv_cat dq arg0_cat, 0
envp_null dq 0
section .bss
pipefds resq 2 ; 2 x 8 bytes (r/w)
section .text
global _start
_start:
; Cria pipe
mov rax, SYS_PIPE
mov rdi, pipefds
syscall
mov r12, [pipefds] ; leitura (pipefds[0])
mov r13, [pipefds + 8] ; escrita (pipefds[1])
; Fork para ls
mov rax, SYS_FORK
syscall
test rax, rax
jz .ls_child
; Fork para cat
mov rax, SYS_FORK
syscall
test rax, rax
jz .cat_child
; Pai: fecha descritores do pipe
mov rax, SYS_CLOSE
mov rdi, r12
syscall
mov rax, SYS_CLOSE
mov rdi, r13
syscall
; Espera dois filhos
xor rdi, rdi
xor rsi, rsi
xor rdx, rdx
mov rax, SYS_WAITPID
syscall
xor rdi, rdi
xor rsi, rsi
xor rdx, rdx
mov rax, SYS_WAITPID
syscall
; Finaliza
mov rax, SYS_EXIT
xor rdi, rdi
syscall
; -----------------------------------------
; Processo filho: ls -l /proc/self/fd
; -----------------------------------------
.ls_child:
; Redireciona stdout → pipe[1]
mov rax, SYS_DUP2
mov rdi, r13 ; escrita
mov rsi, STDOUT_FD
syscall
; Fecha descritores
mov rax, SYS_CLOSE
mov rdi, r12
syscall
mov rax, SYS_CLOSE
mov rdi, r13
syscall
; execve("/bin/ls", ["ls", "-l", "/proc/self/fd"], NULL)
mov rax, SYS_EXECVE
mov rdi, cmd_ls
mov rsi, argv_ls
mov rdx, envp_null
syscall
; Se execve falhar
mov rax, SYS_EXIT
mov rdi, EXIT_FAILURE
syscall
; -----------------------------------------
; Processo filho: cat
; -----------------------------------------
.cat_child:
; Redireciona stdin ← pipe[0]
mov rax, SYS_DUP2
mov rdi, r12 ; leitura
mov rsi, STDIN_FD
syscall
; Fecha descritores
mov rax, SYS_CLOSE
mov rdi, r12
syscall
mov rax, SYS_CLOSE
mov rdi, r13
syscall
; execve("/bin/cat", ["cat"], NULL)
mov rax, SYS_EXECVE
mov rdi, cmd_cat
mov rsi, argv_cat
mov rdx, envp_null
syscall
; Se execve falhar
mov rax, SYS_EXIT
mov rdi, EXIT_FAILURE
syscall