Nasm - tablas de multiplicar

Iniciado por NuevoUsuario, 8 Octubre 2021, 18:47 PM

0 Miembros y 1 Visitante están viendo este tema.

NuevoUsuario

Hola Gente del foro. Estoy aprendiendo Nasm. He escrito un programa que muestra el resultado de las tablas de multiplicar.

Todo bien si pido los resultados de las tablas del 1 al 9, obteniendo la salida por ejemplo en la tabla del 2:

02
04
06..
..12
14
16..
..20

Pero al pedir los resultados de la tabla del 10

no me muestra bien los números, sino que la salida es:

elige una del 2 al 10 10
01
02
3\220
4\300
5
06
07
8\200
9\260
:\340



Podrían ayudarme a resolverlo? Gracias. Este es el código

Código (asm) [Seleccionar]

; pregunta por las tablas de multiplicar

%macro print 2
mov eax, 4
mov ebx, 1
mov ecx, %1
mov edx, %2
int 0x80
%endmacro

%macro read 2
mov eax, 3
mov ebx, 0
mov ecx, %1
mov edx, %2
int 0x80
%endmacro

section .data
msg db "elige una del 2 al 10 "
lenmsg equ $-msg

ln db 0xa, 0xd
lenln equ $-ln

section .bss
tab resb 2
prod resb 3

section .text
global _start

_start:
print msg, lenmsg
push ecx
read tab, 2
pop ecx
mov edi, 1

tabla:
cmp edi, 10
jg exit
mov ax, [tab]
sub ax, '0'
mul edi
cmp ax, 10
jge greater
add ax, '0'
mov [prod], ax
print prod, 2
print ln, lenln
cont:
inc edi
jmp tabla

greater:
clc
aam                                        ; adjust ascii after multiplication
pushf
or ah, 30h
or al, 30h
popf
mov [prod+0], ah
mov [prod+1], al
print prod, 2
print ln, lenln
jmp cont

exit:
mov eax, 1
mov ebx, 0
int 0x80

Eternal Idol

#1
Si escribo 10 en tab habra 2 bytes:
0x31 y 0x30

Código (asm) [Seleccionar]
mov ax, [tab]
sub ax, '0'


Despues de restarle a AX '0' (0x30) tenes:
0x01 y 0x30
La economía nunca ha sido libre: o la controla el Estado en beneficio del Pueblo o lo hacen los grandes consorcios en perjuicio de éste.
Juan Domingo Perón

NuevoUsuario

Ok, entiendo. Gracias por tu tiempo. Buena suerte! \v/

Eternal Idol

La economía nunca ha sido libre: o la controla el Estado en beneficio del Pueblo o lo hacen los grandes consorcios en perjuicio de éste.
Juan Domingo Perón

NuevoUsuario

Hola a todos. Continúo con mi programa de tablas de multiplicar. He agregado lo siguiente: Le pregunto al usuario por la tabla de multiplicar que elija.
Ahora el problema es que aunque responda correctamente me imprime el cartel de error.
Espero que puedan ayudarme, gracias. La salida:

Elige una tabla de multiplicar del 2 al 10 2

2 x 01 = 2
Ok.
2 x 02 = 4
Error.
2 x 03 = 6
Error.
2 x 04 = 8
Error.
2 x 05 =

El código:
Código (asm) [Seleccionar]
; pregunta por las tablas de multiplicar

%macro print 2
mov eax, 4
mov ebx, 1
mov ecx, %1
mov edx, %2
int 0x80
%endmacro

%macro read 2
mov eax, 3
mov ebx, 0
mov ecx, %1
mov edx, %2
int 0x80
%endmacro

section .data
sel db "Elige una tabla de multiplicar del 2 al 10 "
lensel equ $-sel

exis db ' x '
lenx equ $-exis

igual db " = "
leni equ $-igual

ok db "Ok."
lenok equ $-ok

error db "Error."
lenerr equ $-error

ln db 0xa, 0xd
lenln equ $-ln

section .bss
tab resb 2
mult resb 2
res resb 3
prod resb 3

section .text
global _start

_start:
print sel, lensel
read tab, 2
mov edi, 0
tabla:
inc edi
mov ax, [tab]
sub ax, '0'
mul edi
push ax
cmp edi, 9
jg exit
print ln, lenln
add edi, '0' ; paso a ascii
mov [mult], edi
mov bl, [mult+1]
mov bh, [mult+0]
add bx, '0'
mov [mult], bx
print tab, 1
print exis, lenx
print mult, 2
print igual, leni
read res, 2
mov cx, [res]
sub cx, '0'
pop ax
cmp ax, cx
je okey
print error, lenerr
sub edi, '0' ; paso a binario
jmp tabla

okey:
print ok, lenok
sub edi, '0' ; paso a binario
jmp tabla

exit:
mov eax, 1
mov ebx, 0
int 0x80

Eternal Idol

#5
Estas leyendo el salto de linea y usandolo en los calculos.

Primera iteracion del bucle, en tab tenemos:
0x32 y 0x0A

Código (asm) [Seleccionar]
mov ax, [tab]
sub ax, '0'
mul edi
push ax


AX es primero 0x0A32
Al restarle '0' es 0x0A02
multiplicar por 1 no cambia nada
Asi que empujas en la pila 0x0A02

Segunda iteracion del bucle, mismo valor en tab:

AX es primero 0x0A32
Al restarle '0' es 0x0A02
Al mutiplicarlo por 2 AX es 0x1404
Asi que empujas en la pila 0x1404

Tenes exactamente el mismo error de logica al comparar, si aprieto 4 y enter, en res habra esto:

0x34 y 0x0A

Código (asm) [Seleccionar]
mov cx, word ptr [res]
sub cx, '0'
pop ax
cmp ax, cx


De casualidad te funciona en la primera iteracion:
CX es primero 0x0A32
Al restarle '0' es 0x0A02

Coincide con el resultado errado que empujaste en la pila.

En la segunda iteracion:
CX es primero 0x0A34
Al restarle '0' es 0x0A04

0x1404 no es igual a 0x0A04.




Llegados a este punto es imperativo que logres depurar tu programa linea por linea, entiendo que estas usando Linux (yo uso Windows asi que adapte tu codigo a MASM, con todo lo que eso significa partiendo de que los saltos de linea son \r\n y no \n solo como en Linux y las llamadas a la interrupcion 80h tienen que se reemplazadas por las APIs de Windows) asi que busca algun tutorial sobre gdb.
La economía nunca ha sido libre: o la controla el Estado en beneficio del Pueblo o lo hacen los grandes consorcios en perjuicio de éste.
Juan Domingo Perón

NuevoUsuario

#6
Eternal Idol, te agradezco sobremanera. Claro entiendo jaja el primero es acertado de casualidad jajaj.
He usado un poco gdb.
Nunca lo usé en C, pero esto es un poco más complejo jaja.
Mirá si bien programé bastante en C, varias aplicaciones y juegos; al poco andar con assembler noté eso, que mi lógica no era tan buena como yo creía.
Y te voy a decir por qué estoy estudiando ensamblador ahora.
Comencé a desarrollar el juego sudoku en C, con las llibrerías ncurses, y me trabé en una parte asique dije: voy a aprender ensamblador para mejorar y luego retomar el juego. Y aquí estoy, descubriendo mis falencias en lógica.
Con esta ayuda que me diste, además, veo como pensar en assembler. Me sirvió mucho.
Voy a estudiar más así evito preguntar a cada rato. Muchísimas gracias por compartir tu conocimiento y dedicar tu tiempo. Un abrazo.
Voy a leer detenidamente tus comentarios y  mirar el código. Genial gracias!

Eternal Idol

La economía nunca ha sido libre: o la controla el Estado en beneficio del Pueblo o lo hacen los grandes consorcios en perjuicio de éste.
Juan Domingo Perón