在 x86 中使用 atof 函数 NASM
using atof function in x86 NASM
我在让 c 函数 atof() 在我的 asm 程序中工作时遇到了一些问题。我试图从键盘上读取 4 个数字,并最终打印出它们的平均值。然而,在我这样做之前,我需要将数字转换为浮点数。我坚持成功地让我的 'total' 变量工作。我试过在多个地方调用 atof 都无济于事。
这是一个 x86 NASM 程序
; nasm -f elf -l prg2.lst prg2.asm
; gcc -o prg2 prg2.o
; ./prg2
SECTION .DATA
prompt DB 'enter a test score.', 13,10
fmt DB "%s",0
fmtf DB "%f",0
SECTION .bss
test1 resb 1000 ;reserves variable names to
test2 resb 1000 ;put stuff in
test3 resb 1000
test4 resb 1000
total resb 1000
SECTION .code
extern printf
extern scanf
extern atof
global main
main:
push ebp
mov ebp, esp
push prompt
call printf
add esp, 4 ;prompt user
push test1 ;push test1 variable
push fmt
call scanf
add esp, 8 ;store test1 variable
push prompt
call printf
add esp, 4 ;prompt user
push test2 ;push test2 variable
push fmt
call scanf
add esp, 8 ;store test2 variable
push prompt
call printf
add esp, 4 ;prompt user
push test3 ;push test3 variable
push fmt
call scanf
add esp, 8 ;store test3 variable
push prompt
call printf
add esp, 4 ;prompt user
push test4 ;push test4 variable
push fmt
call scanf
add esp, 8 ;store test4 variable
mov eax,[test1]
add eax,[test2]
add eax,[test3]
add eax,[test4]
call atof
mov [total], eax
push total
call printf ;not printing what i want,
add esp,4 ;or printing anything at all
push test1 ;printing scores for verification
call printf
add esp, 4
push test2
call printf
add esp, 4
push test3
call printf
add esp, 4
push test4
call printf
add esp, 4
mov esp, ebp
pop ebp
ret
编辑:修改后,我能够使用这些代码块将输入值转换为各自的数值
mov eax, 0 ;
add eax,[test1] ;put test1 value in eax
mov [total], eax
sub eax, '0'
add eax,[test2]
mov [total], eax
sub eax,'0'
add eax,[test3]
mov [total], eax
sub eax,'0'
add eax,[test4] ;
mov [total], eax
sub eax,'0'
push total
call printf
add esp, 4
样本 运行 通过:
./prg2b
enter a test score.
1
enter a test score.
1
enter a test score.
1
enter a test score.
1
41111
我的代码中的这个添加消除了我的 atof() 调用问题,但只有当数字是一位数并且总数小于 10 时它才会成功
如果有人可以提示如何正确使用 atof,或者如何在使用 scanf 的程序中正确转换为浮点数,我们将不胜感激。我是 x86 asm 的新手(阅读:2 周的学习)。这是在 UNIX 系统的终端中编译的
您可以在 NASM 中使用反引号定义带有转义序列的 C 文字。例如。
prompt DB `enter a test score.\n`, 0 ; Don't forget the last 0
atof
需要堆栈上的内存地址,returns FPU 的寄存器 ST(0) 中的结果。您必须先将每个字符串转换为数字,然后才能使用它进行计算。
SECTION .data
prompt DB `Enter a test score\n`, 0
fmt DB " %s", 0
fmtf DB `Sum: %f\n`, 0
SECTION .bss
test1 resb 1000
test2 resb 1000
test3 resb 1000
test4 resb 1000
double1 resq 1 ; Reserve Quadword = Double
double2 resq 1
double3 resq 1
double4 resq 1
sum resq 1
SECTION .code
extern printf, scanf, atof
global main
main:
push ebp ; Prolog
mov ebp, esp
push prompt ; `enter a test score\n`
call printf
add esp, (1*4) ; Pop 1 dword
push test1
push fmt ; " %s"
call scanf
add esp, (2*4) ; Pop 2 dwords
push test1
call atof
fstp qword [double1]
add esp, (1*4) ; Pop 1 dword
push prompt ; `enter a test score\n`
call printf
add esp, (1*4) ; Pop 1 dword
push test2
push fmt ; " %s"
call scanf
add esp, (2*4) ; Pop 2 dwords
push test2
call atof
fstp qword [double2]
add esp, (1*4) ; Pop 1 dword
push prompt ; `enter a test score\n`
call printf
add esp, (1*4) ; Pop 1 dword
push test3
push fmt ; " %s"
call scanf
add esp, (2*4) ; Pop 2 dwords
push test3
call atof
fstp qword [double3]
add esp, (1*4) ; Pop 1 dword
push prompt ; `enter a test score\n`
call printf
add esp, (1*4) ; Pop 1 dword
push test4
push fmt ; " %s"
call scanf
add esp, (2*4) ; Pop 2 dwords
push test4
call atof
fstp qword [double4]
add esp, (1*4) ; Pop 1 dword
fld qword [double1]
fadd qword [double2]
fadd qword [double3]
fadd qword [double4]
fstp qword [sum]
push dword [sum + 4] ; Push a double in two steps
push dword [sum + 0]
push fmtf ; `result: %f\n`, 0
call printf
add esp, (3*4) ; Pop 3 dwords
mov esp, ebp ; Epilog
pop ebp
ret
你不需要atof
。您可以让 scanf
将输入的字符串转换为格式字符串“ %lf”。
SECTION .data
prompt DB `Enter a test score\n`, 0
fmt DB " %lf", 0 ; scanf needs 'lf' to store a double
fmtf DB `Sum: %f\n`, 0 ; printf needs only 'f' to print a double
SECTION .bss
double1 resq 1 ; Reserve Quadword = Double
double2 resq 1
double3 resq 1
double4 resq 1
sum resq 1
SECTION .code
extern printf, scanf, atof
global main
main:
push ebp ; Prolog
mov ebp, esp
push prompt ; `enter a test score\n`
call printf
add esp, (1*4) ; Pop 1 dword
push double1
push fmt ; " %lf"
call scanf
add esp, (2*4) ; Pop 2 dwords
push prompt ; `enter a test score\n`
call printf
add esp, (1*4) ; Pop 1 dword
push double2
push fmt ; " %lf"
call scanf
add esp, (2*4) ; Pop 2 dwords
push prompt ; `enter a test score\n`
call printf
add esp, (1*4) ; Pop 1 dword
push double3
push fmt ; " %lf"
call scanf
add esp, (2*4) ; Pop 2 dwords
push prompt ; `enter a test score\n`
call printf
add esp, (1*4) ; Pop 1 dword
push double4
push fmt ; " %lf"
call scanf
add esp, (2*4) ; Pop 2 dwords
fld qword [double1]
fadd qword [double2]
fadd qword [double3]
fadd qword [double4]
fstp qword [sum]
push dword [sum + 4] ; Push a double in two steps
push dword [sum + 0]
push fmtf ; `result: %f\n`, 0
call printf
add esp, (3*4) ; Pop 3 dwords
mov esp, ebp ; Epilog
pop ebp
ret
我在让 c 函数 atof() 在我的 asm 程序中工作时遇到了一些问题。我试图从键盘上读取 4 个数字,并最终打印出它们的平均值。然而,在我这样做之前,我需要将数字转换为浮点数。我坚持成功地让我的 'total' 变量工作。我试过在多个地方调用 atof 都无济于事。
这是一个 x86 NASM 程序
; nasm -f elf -l prg2.lst prg2.asm
; gcc -o prg2 prg2.o
; ./prg2
SECTION .DATA
prompt DB 'enter a test score.', 13,10
fmt DB "%s",0
fmtf DB "%f",0
SECTION .bss
test1 resb 1000 ;reserves variable names to
test2 resb 1000 ;put stuff in
test3 resb 1000
test4 resb 1000
total resb 1000
SECTION .code
extern printf
extern scanf
extern atof
global main
main:
push ebp
mov ebp, esp
push prompt
call printf
add esp, 4 ;prompt user
push test1 ;push test1 variable
push fmt
call scanf
add esp, 8 ;store test1 variable
push prompt
call printf
add esp, 4 ;prompt user
push test2 ;push test2 variable
push fmt
call scanf
add esp, 8 ;store test2 variable
push prompt
call printf
add esp, 4 ;prompt user
push test3 ;push test3 variable
push fmt
call scanf
add esp, 8 ;store test3 variable
push prompt
call printf
add esp, 4 ;prompt user
push test4 ;push test4 variable
push fmt
call scanf
add esp, 8 ;store test4 variable
mov eax,[test1]
add eax,[test2]
add eax,[test3]
add eax,[test4]
call atof
mov [total], eax
push total
call printf ;not printing what i want,
add esp,4 ;or printing anything at all
push test1 ;printing scores for verification
call printf
add esp, 4
push test2
call printf
add esp, 4
push test3
call printf
add esp, 4
push test4
call printf
add esp, 4
mov esp, ebp
pop ebp
ret
编辑:修改后,我能够使用这些代码块将输入值转换为各自的数值
mov eax, 0 ;
add eax,[test1] ;put test1 value in eax
mov [total], eax
sub eax, '0'
add eax,[test2]
mov [total], eax
sub eax,'0'
add eax,[test3]
mov [total], eax
sub eax,'0'
add eax,[test4] ;
mov [total], eax
sub eax,'0'
push total
call printf
add esp, 4
样本 运行 通过:
./prg2b
enter a test score.
1
enter a test score.
1
enter a test score.
1
enter a test score.
1
41111
我的代码中的这个添加消除了我的 atof() 调用问题,但只有当数字是一位数并且总数小于 10 时它才会成功
如果有人可以提示如何正确使用 atof,或者如何在使用 scanf 的程序中正确转换为浮点数,我们将不胜感激。我是 x86 asm 的新手(阅读:2 周的学习)。这是在 UNIX 系统的终端中编译的
您可以在 NASM 中使用反引号定义带有转义序列的 C 文字。例如。
prompt DB `enter a test score.\n`, 0 ; Don't forget the last 0
atof
需要堆栈上的内存地址,returns FPU 的寄存器 ST(0) 中的结果。您必须先将每个字符串转换为数字,然后才能使用它进行计算。
SECTION .data
prompt DB `Enter a test score\n`, 0
fmt DB " %s", 0
fmtf DB `Sum: %f\n`, 0
SECTION .bss
test1 resb 1000
test2 resb 1000
test3 resb 1000
test4 resb 1000
double1 resq 1 ; Reserve Quadword = Double
double2 resq 1
double3 resq 1
double4 resq 1
sum resq 1
SECTION .code
extern printf, scanf, atof
global main
main:
push ebp ; Prolog
mov ebp, esp
push prompt ; `enter a test score\n`
call printf
add esp, (1*4) ; Pop 1 dword
push test1
push fmt ; " %s"
call scanf
add esp, (2*4) ; Pop 2 dwords
push test1
call atof
fstp qword [double1]
add esp, (1*4) ; Pop 1 dword
push prompt ; `enter a test score\n`
call printf
add esp, (1*4) ; Pop 1 dword
push test2
push fmt ; " %s"
call scanf
add esp, (2*4) ; Pop 2 dwords
push test2
call atof
fstp qword [double2]
add esp, (1*4) ; Pop 1 dword
push prompt ; `enter a test score\n`
call printf
add esp, (1*4) ; Pop 1 dword
push test3
push fmt ; " %s"
call scanf
add esp, (2*4) ; Pop 2 dwords
push test3
call atof
fstp qword [double3]
add esp, (1*4) ; Pop 1 dword
push prompt ; `enter a test score\n`
call printf
add esp, (1*4) ; Pop 1 dword
push test4
push fmt ; " %s"
call scanf
add esp, (2*4) ; Pop 2 dwords
push test4
call atof
fstp qword [double4]
add esp, (1*4) ; Pop 1 dword
fld qword [double1]
fadd qword [double2]
fadd qword [double3]
fadd qword [double4]
fstp qword [sum]
push dword [sum + 4] ; Push a double in two steps
push dword [sum + 0]
push fmtf ; `result: %f\n`, 0
call printf
add esp, (3*4) ; Pop 3 dwords
mov esp, ebp ; Epilog
pop ebp
ret
你不需要atof
。您可以让 scanf
将输入的字符串转换为格式字符串“ %lf”。
SECTION .data
prompt DB `Enter a test score\n`, 0
fmt DB " %lf", 0 ; scanf needs 'lf' to store a double
fmtf DB `Sum: %f\n`, 0 ; printf needs only 'f' to print a double
SECTION .bss
double1 resq 1 ; Reserve Quadword = Double
double2 resq 1
double3 resq 1
double4 resq 1
sum resq 1
SECTION .code
extern printf, scanf, atof
global main
main:
push ebp ; Prolog
mov ebp, esp
push prompt ; `enter a test score\n`
call printf
add esp, (1*4) ; Pop 1 dword
push double1
push fmt ; " %lf"
call scanf
add esp, (2*4) ; Pop 2 dwords
push prompt ; `enter a test score\n`
call printf
add esp, (1*4) ; Pop 1 dword
push double2
push fmt ; " %lf"
call scanf
add esp, (2*4) ; Pop 2 dwords
push prompt ; `enter a test score\n`
call printf
add esp, (1*4) ; Pop 1 dword
push double3
push fmt ; " %lf"
call scanf
add esp, (2*4) ; Pop 2 dwords
push prompt ; `enter a test score\n`
call printf
add esp, (1*4) ; Pop 1 dword
push double4
push fmt ; " %lf"
call scanf
add esp, (2*4) ; Pop 2 dwords
fld qword [double1]
fadd qword [double2]
fadd qword [double3]
fadd qword [double4]
fstp qword [sum]
push dword [sum + 4] ; Push a double in two steps
push dword [sum + 0]
push fmtf ; `result: %f\n`, 0
call printf
add esp, (3*4) ; Pop 3 dwords
mov esp, ebp ; Epilog
pop ebp
ret