Nasm,没有打印正确的值
Nasm, not printing the correct value
我做了一个 nasm 程序来计算特定大小的两个向量之间的欧几里得距离。
这个 nasm 函数是从 C 文件调用的,该文件获取函数的结果。我已经测试过了,它可以工作,返回的值是正确的,我可以毫无问题地打印它。
我的问题是当我尝试在 nasm 文件中打印结果时。
这是 nasm 代码:
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
这是 C 文件:
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);
这是输出:
distanza, dist: 5.46877e-315
d(x,y) = 31.227551
C 代码打印出正确的值,nasm 却没有。
如果我更改 nasm 代码的格式字符串:
fmt2: db "%s, dist: %f",10,0
我用了 %f 而不是 %g,nasm 输出是这个:
distanza, dist: 0.000000
我不知道我的代码有什么问题,为什么它没有打印正确的值?
您的 dist
是一个 32 位浮点数,但 printf
需要一个双 64 位浮点数。你必须改造它:
%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
我做了一个 nasm 程序来计算特定大小的两个向量之间的欧几里得距离。 这个 nasm 函数是从 C 文件调用的,该文件获取函数的结果。我已经测试过了,它可以工作,返回的值是正确的,我可以毫无问题地打印它。 我的问题是当我尝试在 nasm 文件中打印结果时。 这是 nasm 代码:
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
这是 C 文件:
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);
这是输出:
distanza, dist: 5.46877e-315
d(x,y) = 31.227551
C 代码打印出正确的值,nasm 却没有。 如果我更改 nasm 代码的格式字符串:
fmt2: db "%s, dist: %f",10,0
我用了 %f 而不是 %g,nasm 输出是这个:
distanza, dist: 0.000000
我不知道我的代码有什么问题,为什么它没有打印正确的值?
您的 dist
是一个 32 位浮点数,但 printf
需要一个双 64 位浮点数。你必须改造它:
%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