NASM - The Netwide Assembler
NASM Forum => Programming with NASM => Topic started by: emisaeljcr on April 29, 2011, 06:12:43 PM
-
Hi, i comeback trying to pass a tasm macro to nasm, but im not so clearly in how its work, i tried only moving the undeclared to .bss and adding the length of strings that doesnt have it, when assembly it gave me a lot of errors, i guess that the macro and the proc are not like i used.
;nasm -f elf s.asm
;ld -s -o s s.o
;./suma
SECTION .data
;variables utilizadas por las macros
diezInt: dd 10
diezReal: dd 10.0
menos: dd -1.0
tam: dw 40
error1: db "Desbordamiento de cadena",10
lerror1: equ $-error1
;fin variables
cadena1: db "140",10
cadena2: db "1000",10
mensaje: db "El resultado es: ",10
lmensaje: equ $-mensaje
ent: db 10,13,'$'
;MACROS
;Macro que convierte una cadena en numero en coma flotante
ConvertirStrReal Macro cadStr,cadReal
Lea ebx,cadStr
push ebx
lea ebx,cadReal
push ebx
call strToFloat
endM
;Macro que convierte un numero en coma flotante a cadena
ConvertirRealStr macro cadReal,cadStr,precision
Lea ebx,cadReal
push ebx
Lea ebx,cadStr
push ebx
push word ptr precision
call floatToStr
endM
SECTION .bss
cadtemp: resb 40
cadena3: resb 40
real1: resb 255
real2: resb 255
result: resb 255
;variables para las macros
lugares: resb 255
entero: resb 255
signo: resb 255
SECTION .text
global _start
_start:
;msj1
mov edx,len1
mov ecx,msg1
mov ebx,1
mov eax,4
int 0x80
;introducir n1
mov edx,255
mov ecx,n1
mov ebx,0
mov eax,3
int 80h
.486
;Este ejemplo multiplica -244.3 * 6
ConvertirStrReal cadena2,real2
fld real1 ;carga en la FPU el numero -244.3
fld real2 ;carga en la FPU el numero 6
fmul ; -244.3*6
fstp [result] ;almacena el resultado en la variable result
convertirRealStr result,cadena3,2
mov edx,lmensaje
mov ecx,mensaje
mov ebx,1
mov eax,4
int 0x80
mov edx,10
mov ecx,cadena3
mov ebx,1
mov eax,4
int 0x80
;terminar
mov ebx,0
mov eax,1
int 0x80
;Convierte una cadena en punto flotante y lo carga en la FPU mediante el siguiente procedimiento;
;1- Verifica si el primer caracter es un - y lo almacena en la variable signo (0-positivo 1-negativo)
;2- Cuenta el numero de lugares despues de la coma y lo almacena en la variables lugares
;3- Construye el equivalente entero de la cadena. Para ello agarra cada numero y le resta 30h para transformarlo a decimal. Luego lo acumula
; en EAX.Por ultimo lo multiplica por 10. Y asi por cada numero
;4- Carga el numero entero en la FPU
;5- Divide entre 10.0 el numero de veces que lo indique la variable lugares
;6- Si la variable signo tiene 1, multiplica el numero restante por -1
Proc strToFloat
locals
Mov [lugares],0
Mov [signo],0
Mov SI,0
lea ebx,cadtemp
inicializarCadena:
Mov byte ptr [BX+SI],' '
INC SI
cmp SI,[tam]
JNE inicializarCadena
push bp
mov bp,sp
Mov SI,0
Mov ebx,[BP+6]
cmp byte ptr [BX+SI],'-'
JE @Signo
jmp CicloComa
@Signo:
inc [signo]
CicloComa:
Mov DL,[BX+SI]
INC SI
cmp DL,'$'
JE @Entero ;en el caso de que ya sea un numero entero
cmp DL,','
JNE CicloComa
CicloContarDecimales:
INC [lugares]
INC SI
cmp byte ptr [BX+SI],'$'
JNE CicloContarDecimales
@entero:
Mov SI,0h
Mov eax,0h
CicloInteger:
Mov ecx,0
Mov CL,[BX+SI]
CMP CL,','
JE ASCII
CMP CL,'-'
JE ASCII
SUB CL,30h
ADD eax, ecx
MUL diezInt
ASCII:
INC SI
cmp byte ptr [BX+SI],'$'
JNE CicloInteger
DIV diezInt
Mov [entero],eax
FPU:
finit
fild entero
mov ecx,0
CicloDivisiones:
cmp ecx,[lugares]
JE ComprobarSigno
fld diezReal
fdivp
inc ecx
jmp CicloDivisiones
ComprobarSigno:
cmp [signo],1
JE Negativo
jmp FinStrToFloat
Negativo:
fld menos
fmulp
FinStrToFloat:
MOV ebx,[BP+4]
fstp dword ptr [ebx] ;carga el resultado en la variable indicada por el usuario
pop BP
ret 4
strToFloat Endp
Proc floatToStr
locals
Mov [lugares],0
Mov [signo],0
Mov SI,0
lea ebx,cadtemp
@inicializarCadena:
Mov byte ptr [ebx+SI],' '
INC SI
cmp SI,[tam]
JNE @inicializarCadena
Push BP
Mov BP,SP
Mov CX,[BP+4]
Mov [lugares],CX
Mov ebx,[BP+8]
finit
fld dword ptr [ebx] ;carga el numero real
CicloMoverComa: ;multiplica por diez el numero de veces indicado por el usuario
fld diezReal
fmulp
fwait
dec ecx
cmp ecx,0
JNE CicloMoverComa
EvaluarSigno:
ftst ;comprueba si el numero es negativo
fwait
fstsw eax ;carga las banderas en ax
fwait
sahf ;carga el valor de AL en el registro de flags
jb @negativo
jmp @positivo
@negativo:
Mov [signo],1
@positivo:
fabs ;convierte el numero a positivo
fist [entero] ;redondea y almacena el valor en la variable entero
fwait
Mov SI,0
Mov eax,[entero]
Lea ebx,cadTemp
Mov byte ptr [ebx+SI],'$'
CicloConstruirCadena: ;construye la cadena de atras hacia adelante
cdq
IDIV [diezInt] ;descompone el numero entero dividiendo entre diez
INC SI
add DL,30h
Mov [ebx+SI],DL
cmp SI,[lugares]
JE @coma ;agrega la coma si es un numero flotante
@noComa:
cmp SI,[tam]
JE @Error1
cmp eax,0
JNE CicloConstruirCadena
jmp @agregarMenos
@Coma:
INC SI
Mov byte ptr [ebx+SI],','
jmp @noComa
@agregarMenos: ;agrega el signo en caso de ser negativo
cmp [signo],1
JE @menos
jmp InvertirCadena
@menos:
INC SI
Mov byte ptr [ebx+SI],'-'
InvertirCadena: ;invierte la cadena
jmp FinFloatToStr
@Error1:
;msj1
mov edx,lerror1
mov ecx,error1
mov ebx,1
mov eax,4
int 0x80
FinFloatToStr: ;copia la cadena resultante en la cadena de salida
Mov DI,[BP+6]
Lea ebx,cadTemp
Copiar:
Mov CL,[ebx+SI]
Mov byte ptr [DI],CL
DEC SI
INC DI
cmp SI,0
JNE Copiar
Mov byte ptr [DI],'$'
Pop BP
ret 6
floatToStr endP
end
Making it by myself is very difficult, i dont understand a lot of things, i need more experience to do it, i can make it in tasm but i get more points in nasm, its a homework, understand me? :(
this is my error list:
s.asm:25: error: parser: instruction expected
s.asm:34: error: parser: instruction expected
s.asm:39: error: comma, colon or end of line expected
s.asm:41: error: symbol `endM' redefined
s.asm:76: error: symbol `ConvertirStrReal' redefined
s.asm:76: error: parser: instruction expected
s.asm:82: error: parser: instruction expected
s.asm:108: error: parser: instruction expected
s.asm:115: error: comma, colon or end of line expected
s.asm:124: error: comma, colon or end of line expected
s.asm:140: error: comma, colon or end of line expected
s.asm:160: error: comma, colon or end of line expected
s.asm:186: error: comma, colon or end of line expected
s.asm:189: error: parser: instruction expected
s.asm:191: error: symbol `Proc' redefined
s.asm:191: error: parser: instruction expected
s.asm:192: error: symbol `locals' redefined
s.asm:198: error: comma, colon or end of line expected
s.asm:208: error: comma, colon or end of line expected
s.asm:234: error: comma, colon or end of line expected
s.asm:240: error: impossible combination of address sizes
s.asm:240: error: invalid effective address
s.asm:251: error: comma, colon or end of line expected
s.asm:260: error: comma, colon or end of line expected
s.asm:280: error: impossible combination of address sizes
s.asm:280: error: invalid effective address
s.asm:281: error: comma, colon or end of line expected
s.asm:286: error: comma, colon or end of line expected
s.asm:290: error: parser: instruction expected
i will pass everything to english later, when i arrive to home.
-
Yow! You're right, you haven't got enough experience to do this. If the homework assignment expects you to write your own string-to-float and float-to-string routines, it's much too difficult. Drop the course! (only semi-joking)
Translating the macros from Tasm to Nasm requires a little experience, too, but you don't "need" macros. I'd suggest you get it working without macros, first. Then, once you understand what the macros need to do, write the macros!
Your subroutines are a weird mixture of 16-bit and 32-bit code. A lot of it isn't even legal ("[ebx + si]" and such). You can use 16-bit registers in 32-bit code, but you rarely need to. I'd change the 16-bit registers to 32-bit registers, for a start. That'll get rid of some of the Nasm errors, at least.
Even if you're required to accept floating point, you might want to finish up the integer version first. You had a good start at that. If you're allowed to use "scanf" and "printf", that would be a lot easier than trying to write your own conversion routines. (scanf requires the address of a float as a parameter, and printf always expects a double-precision float - those are the tricky parts!) What does the homework assignment require, anyway?
Here's an example that includes homemade string-to-float and float-to-string routines. They are VERY POOR! They don't check for overflow, and will give wrong results easily. I get around this (somewhat) by limiting the number of characters that can be entered. :) I wouldn't give myself a very good grade on it, but it more-or-less "works". Use scanf and printf if you can!
Best,
Frank