简体   繁体   中英

Nasm, not printing the correct value

I've made a nasm procedure that calculates the eucledian distance between two vectors of a certain size. This nasm function is called from a C file which get the result of the function. I've tested, and it works, the value returned is correct, I can print it withoud any problem. My issue is when I try to print the result inside the nasm file. This is the nasm code:

extern printf

%macro print_dist2 1

section .data
.str db %1,0                    ; %1 is macro call first actual parameter
section .text

push dword [dist]
push dword .str
push dword fmt2
call printf
add esp, 12                     ; pop stack 3 * 4 bytes

%endmacro




section .data           

dist: dd 258                    

fmt2: db "%s, dist: %g",10,0     ; format string for printf

section .bss            


section .text           

global distanza

x   equ 8
y   equ 12
dim equ 16
ris equ 20


distanza:
    ; ------------------------------------------------------------
    ; Function entrance sequence
    ; ------------------------------------------------------------
    push    ebp     
    mov ebp, esp    
    push    ebx     
    push    esi
    push    edi
    ; ------------------------------------------------------------
    ; read the parameters from the current stack frame
    ; ------------------------------------------------------------



    mov eax, [ebp+x]    ; address of x
    mov ebx, [ebp+y]    ; address of y
    mov ecx, [ebp+dim]  ; size of the vectors (it's the same)
.
.
. omitted calculations.
.

    sqrtss  xmm1, xmm1
    movss   [dist], xmm1    ; move the result to dist
    fld     dword [dist]    ; mov in st0, that will be used by the C file 

    print_dist2 "distanza"

    ; ------------------------------------------------------------
    ; Function exit sequence
    ; ------------------------------------------------------------

    pop edi     
    pop esi
    pop ebx
    mov esp, ebp    
    pop ebp     
    ret         

This is the C file:

 float a[] = {6.1f, 9.5f, 12.6f};
 float b[] = {25.1f, 34.1f, 9.6f};
 dim = 3;

 float dist = distanza(a, b, dim);

 printf("d(x,y) = %f\n", dist);

This is the output:

distanza, dist: 5.46877e-315
d(x,y) = 31.227551

The C, code print the correct value, the nasm doesn't. If I change the format string of the nasm code:

fmt2: db "%s, dist: %f",10,0

I've used %f instead of %g, the nasm output is this one:

distanza, dist: 0.000000

I have no idea what is wrong with my code, why it is not printing the correct value?

Your dist is a single 32-bit float, but printf needs a double 64-bit float. You have to transform it:

%macro print_dist2 1

section .data
.str db %1,0                    ; %1 is macro call first actual parameter
section .text

sub esp, 8                      ; Space for a 64-bit double floating point number
fld dword [dist]                ; Load a 32-bit single floating point number
fstp qword [esp]                ; Store it as 64-bit floating point number
push dword .str
push dword fmt2
call printf
add esp, 16                     ; pop stack 4 * 4 bytes

%endmacro

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM