Compare commits
No commits in common. "f53ec7dcf6d9d0bd542a6e49df2649b057306aa8" and "7c9155a262b86adacc5d3814064dd044b51033a9" have entirely different histories.
f53ec7dcf6
...
7c9155a262
5 changed files with 1 additions and 1546 deletions
|
@ -59,7 +59,7 @@ própria, sob os termos da licença [[https://bolha.dev/blau_araujo/pbn/src/bran
|
||||||
| 14/07 | 6. [[curso/aula-06.org][Vetor de argumentos de linha de comando]] |
|
| 14/07 | 6. [[curso/aula-06.org][Vetor de argumentos de linha de comando]] |
|
||||||
| 16/07 | 7. [[curso/aula-07.org][Vetor de ambiente]] |
|
| 16/07 | 7. [[curso/aula-07.org][Vetor de ambiente]] |
|
||||||
| 18/07 | 8. [[curso/aula-08.org][Fluxos de dados]] |
|
| 18/07 | 8. [[curso/aula-08.org][Fluxos de dados]] |
|
||||||
| 21/07 | 9. [[curso/aula-09.org][Conversão de strings numéricas para inteiros]] |
|
| 21/07 | 9. Conversão de caracteres para números |
|
||||||
| 23/07 | 10. Conversão de números para caracteres |
|
| 23/07 | 10. Conversão de números para caracteres |
|
||||||
| 25/07 | 11. Conversão de bases de numeração |
|
| 25/07 | 11. Conversão de bases de numeração |
|
||||||
| 28/07 | 12. Bibliotecas de macros e sub-rotinas |
|
| 28/07 | 12. Bibliotecas de macros e sub-rotinas |
|
||||||
|
|
1351
curso/aula-09.org
1351
curso/aula-09.org
File diff suppressed because it is too large
Load diff
|
@ -1,14 +0,0 @@
|
||||||
#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;
|
|
||||||
}
|
|
|
@ -1,129 +0,0 @@
|
||||||
; ----------------------------------------------------------
|
|
||||||
; 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
|
|
|
@ -1,51 +0,0 @@
|
||||||
/*
|
|
||||||
* 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;
|
|
||||||
}
|
|
Loading…
Add table
Reference in a new issue