diretórios 8 e 13 de exemplos
This commit is contained in:
parent
62338a8185
commit
6fbe5f3a62
13 changed files with 820 additions and 0 deletions
76
curso/exemplos/08/#sint.asm#
Normal file
76
curso/exemplos/08/#sint.asm#
Normal 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
|
193
curso/exemplos/08/.gdb_history
Normal file
193
curso/exemplos/08/.gdb_history
Normal 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
|
14
curso/exemplos/08/exemplo.c
Normal file
14
curso/exemplos/08/exemplo.c
Normal 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;
|
||||||
|
}
|
27
curso/exemplos/08/limites.c
Normal file
27
curso/exemplos/08/limites.c
Normal 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;
|
||||||
|
}
|
76
curso/exemplos/08/sint.asm
Normal file
76
curso/exemplos/08/sint.asm
Normal 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
129
curso/exemplos/08/uint.asm
Normal 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
51
curso/exemplos/08/uint.c
Normal 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;
|
||||||
|
}
|
107
curso/exemplos/13/.gdb_history
Normal file
107
curso/exemplos/13/.gdb_history
Normal 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
|
1
curso/exemplos/13/mensagem.txt
Normal file
1
curso/exemplos/13/mensagem.txt
Normal file
|
@ -0,0 +1 @@
|
||||||
|
Salve, simpatia!
|
146
curso/exemplos/13/teste.asm
Normal file
146
curso/exemplos/13/teste.asm
Normal 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
|
Loading…
Add table
Reference in a new issue