Exercício da aula 13 #28

Open
opened 2025-07-31 21:28:36 -03:00 by blau_araujo · 2 comments
Owner

Ainda em desenvolvimento...

%define BUF_SIZE 21

section .bss
	buffer resb BUF_SIZE
	
section .text
global _start
_start:

	; - receber valor pela digitação

	xor rax, rax
	xor rdi, rdi
	mov rsi, buffer
	mov rdx, BUF_SIZE
	syscall			; retona qtd bytes lidos em rax

	; converter caracteres em números
_convert:
	dec rax
	mov byte [buffer + rax], 0	; garante terminador nulo
	mov rbx, 10		; multiplicador por 10
	xor rcx, rcx		; contador = 0
	xor rax, rax		; resultados
.digit_loop:
	mov r8b, byte [buffer + rcx]
	cmp r8b, '0' 		; se menor, inválido
	jl .done
	cmp r8b, '9'		; se maior, inválido
	jg .done
	sub r8b, 0x30		; converter para int
	mul rbx			; rax = rax × 10
	add rax, r8		; rax = rax + r8b
	inc rcx
	jmp .digit_loop
.done:
	add rax, rcx
	jz _exit_err
	
	; - somar esse valor com 42


	
	; - imprimir resultado (definir como status)

	mov rax, 60
	xor rdi, rdi
	syscall

_exit_err:
	mov rax, 60
	mov rdi, 42
	syscall
Ainda em desenvolvimento... ```asm %define BUF_SIZE 21 section .bss buffer resb BUF_SIZE section .text global _start _start: ; - receber valor pela digitação xor rax, rax xor rdi, rdi mov rsi, buffer mov rdx, BUF_SIZE syscall ; retona qtd bytes lidos em rax ; converter caracteres em números _convert: dec rax mov byte [buffer + rax], 0 ; garante terminador nulo mov rbx, 10 ; multiplicador por 10 xor rcx, rcx ; contador = 0 xor rax, rax ; resultados .digit_loop: mov r8b, byte [buffer + rcx] cmp r8b, '0' ; se menor, inválido jl .done cmp r8b, '9' ; se maior, inválido jg .done sub r8b, 0x30 ; converter para int mul rbx ; rax = rax × 10 add rax, r8 ; rax = rax + r8b inc rcx jmp .digit_loop .done: add rax, rcx jz _exit_err ; - somar esse valor com 42 ; - imprimir resultado (definir como status) mov rax, 60 xor rdi, rdi syscall _exit_err: mov rax, 60 mov rdi, 42 syscall ```
Author
Owner

Para adiantar, eu já atualizei o exercício com algumas verificações. Estudem o código pra gente discutir na aula... ;-)

%define BUF_SIZE  21
%define E_NUMB    42
%define E_OVER    23
%define MUL10_MAX 922337203685477580

section .bss
   buf resb BUF_SIZE	; i64: 19 dígitos + 1 sinal + '\0' (21 bytes)
   
section .text
global _start
_start:

   ; receber valor pela digitação
   xor rax, rax
   xor rdi, rdi
   mov rsi, buf
   mov rdx, BUF_SIZE - 1	; como 'fgets()', lê até size-1
   syscall			; retorna qtd de bytes lidos em rax
   
_check_read:
   cmp rax, 0		; se rax  == 0, é erro
   je _exit_err
   mov byte [buf+rax], 0	; garante terminador nulo
   
   ; converter caracteres em números
_convert:
   xor rax, rax		; resultados
   mov rbx, 10		; multiplicador por 10
   xor rcx, rcx		; índice = 0
   xor rdx, rdx		; dígitos convertidos
   xor r9, r9		; flag de sinal
.test_sig:
   mov r8b, byte [buf+rcx]	; carrega primeiro caractere
.check_minus:
   cmp r8b, '-'		; tem sinal de negativo?
   jne .check_plus
   inc r9			; flag de sinal = 1 (negativo)
   inc rcx			; avança para próximo caractere
   jmp .digit_loop
.check_plus:
   cmp r8b, '+'		; tem sinal de positivo?
   jne .check_digit
   inc rcx			; só avança para próximo caractere
.digit_loop:
   mov r8b, byte [buf+rcx]	; carrega caractere seguinte
.check_digit:
   cmp r8b, '0' 		; se menor, termina
   jl .check_count
   cmp r8b, '9'		; se maior, termina
   jg .check_count
   sub r8b, 0x30		; converter para int
.check_i64max:			; isso sacrifica INT64_MIN
   mov r10, MUL10_MAX	; INT64_MAX / 10
   cmp rax, r10		; se maior, overflow
   ja _exit_overflow
   jb .safe
   cmp r8b, 7		; rax == MUL10_MAX, só pode somar até 7
   ja _exit_overflow
.safe:
   mul rbx			; rax = rax × 10
   add rax, r8		; rax = rax + r8b
   inc rcx			; índice do próximo caractere
   inc rdx			; incrementa contagem de dígitos
   jmp .digit_loop
.check_count:
   cmp rdx, 0		; se rcx == 0, nada foi convertido
   je _exit_err
.negative:
   cmp r9, 0		; negativo?
   je .done
   neg rax			; torna negativo
.done:

   ; verificar se pode somar (NUM <= INT64_MAX-valor)
   ; somar rax valor com 42
   add rax, 42

   ; converter soma para string
   
   ; imprimir resultado

_exit_ok:
   xor rdi, rdi
   jmp _exit
_exit_err:
   mov rdi, E_NUMB
   jmp _exit
_exit_overflow:
   mov rdi, E_OVER
_exit:
   mov rax, 60
   syscall
Para adiantar, eu já atualizei o exercício com algumas verificações. Estudem o código pra gente discutir na aula... ;-) ```asm %define BUF_SIZE 21 %define E_NUMB 42 %define E_OVER 23 %define MUL10_MAX 922337203685477580 section .bss buf resb BUF_SIZE ; i64: 19 dígitos + 1 sinal + '\0' (21 bytes) section .text global _start _start: ; receber valor pela digitação xor rax, rax xor rdi, rdi mov rsi, buf mov rdx, BUF_SIZE - 1 ; como 'fgets()', lê até size-1 syscall ; retorna qtd de bytes lidos em rax _check_read: cmp rax, 0 ; se rax == 0, é erro je _exit_err mov byte [buf+rax], 0 ; garante terminador nulo ; converter caracteres em números _convert: xor rax, rax ; resultados mov rbx, 10 ; multiplicador por 10 xor rcx, rcx ; índice = 0 xor rdx, rdx ; dígitos convertidos xor r9, r9 ; flag de sinal .test_sig: mov r8b, byte [buf+rcx] ; carrega primeiro caractere .check_minus: cmp r8b, '-' ; tem sinal de negativo? jne .check_plus inc r9 ; flag de sinal = 1 (negativo) inc rcx ; avança para próximo caractere jmp .digit_loop .check_plus: cmp r8b, '+' ; tem sinal de positivo? jne .check_digit inc rcx ; só avança para próximo caractere .digit_loop: mov r8b, byte [buf+rcx] ; carrega caractere seguinte .check_digit: cmp r8b, '0' ; se menor, termina jl .check_count cmp r8b, '9' ; se maior, termina jg .check_count sub r8b, 0x30 ; converter para int .check_i64max: ; isso sacrifica INT64_MIN mov r10, MUL10_MAX ; INT64_MAX / 10 cmp rax, r10 ; se maior, overflow ja _exit_overflow jb .safe cmp r8b, 7 ; rax == MUL10_MAX, só pode somar até 7 ja _exit_overflow .safe: mul rbx ; rax = rax × 10 add rax, r8 ; rax = rax + r8b inc rcx ; índice do próximo caractere inc rdx ; incrementa contagem de dígitos jmp .digit_loop .check_count: cmp rdx, 0 ; se rcx == 0, nada foi convertido je _exit_err .negative: cmp r9, 0 ; negativo? je .done neg rax ; torna negativo .done: ; verificar se pode somar (NUM <= INT64_MAX-valor) ; somar rax valor com 42 add rax, 42 ; converter soma para string ; imprimir resultado _exit_ok: xor rdi, rdi jmp _exit _exit_err: mov rdi, E_NUMB jmp _exit _exit_overflow: mov rdi, E_OVER _exit: mov rax, 60 syscall ```
Author
Owner

Para fazer o flush do terminal com a chamada ioctl:

	; receber valor pela digitação
	xor rax, rax
	xor rdi, rdi
	mov rsi, buf
	mov rdx, BUF_SIZE - 1	; como 'fgets()', lê até size-1
	syscall			; retorna qtd de bytes lidos em rax

	push rax            ; salva rax na pilha
	
	; ioctl(FD0, TCFLSH, TCIFLUSH)
	
	mov rax, 16         ; syscall ioctl
	xor rdi, rdi        ; fd = 0 (stdin)
	mov rsi, 0x540B	    ; TCFLSH -> /usr/include/asm-generic/ioctls.h
	xor rdx, rdx        ; TCIFLUSH -> /usr/include/asm-generic/termbits-common.h
	syscall

	pop rax             ; restaura rax
Para fazer o flush do terminal com a chamada `ioctl`: ```asm ; receber valor pela digitação xor rax, rax xor rdi, rdi mov rsi, buf mov rdx, BUF_SIZE - 1 ; como 'fgets()', lê até size-1 syscall ; retorna qtd de bytes lidos em rax push rax ; salva rax na pilha ; ioctl(FD0, TCFLSH, TCIFLUSH) mov rax, 16 ; syscall ioctl xor rdi, rdi ; fd = 0 (stdin) mov rsi, 0x540B ; TCFLSH -> /usr/include/asm-generic/ioctls.h xor rdx, rdx ; TCIFLUSH -> /usr/include/asm-generic/termbits-common.h syscall pop rax ; restaura rax ```
Sign in to join this conversation.
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: blau_araujo/pbn#28
No description provided.