在x86 NASM中使用atof函数 [英] using atof function in x86 NASM

查看:304
本文介绍了在x86 NASM中使用atof函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一些麻烦得到c函数atof()在我的asm程序中工作。我试图从键盘上读取4个数字,最终打印出他们的平均值。然而,在我能做到这一点之前,我需要将数字转换为浮点数。我坚持成功让我的'总'变量工作。我已经尝试过在多个地方调用atof无济于事。

这是一个x86 NASM程序

pre > ; nasm -f elf -l prg2.lst prg2.asm
; gcc -o prg2 prg2.o
; ./prg2

SECTION .DATA

提示DB'输入测试分数',13,10
fmt DB%s,0
fmtf DB%f,0


SECTION .bss
test1 resb 1000;保留变量名称到
test2 resb 1000;把东西放入
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;提示用户

push test1; push test1变量
push fmt
call scanf
add esp,8; store test1变量

推送提示符
调用printf
add esp,4;提示用户
$ b $推测试2;推测试2变量
推送文件
调用scanf
add esp,8;存储test2变量

推送提示
调用printf
添加esp,4;提示用户

push test3; push test3变量
push fmt
call scanf
add esp,8; store test3变量

推送提示
call printf
add esp,4;提示用户

push test4; push test4变量
push fmt
call scanf
add esp,8; store test4变量

mov eax,[test1]
add eax,[test2]
add eax,[test3]
add eax,[test4]

call atof
mov [total],eax

push total
call printf;不打印我想要的,
add esp,4;或者打印任何东西在所有

push test1;打印分数验证
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];把test1的值放入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 
输入一个测试分数。
1
输入一个测试分数。
1
输入一个测试分数。
1
输入一个测试分数。
1
41111

这个除了我的代码可以摆脱我的问题atof()调用,但是只有当数字是一位数字,并且如果总数是< 10



,则它才是成功的如果任何人都可以提供关于如何正确使用atof,或如何正确地转换为使用scanf的程序中的浮点数,将不胜感激。我很新(阅读:2周的学习)到x86 asm。这是在UNIX系统的终端中编译的。您可以使用反引号在NASM中定义带有转义序列的C文本。例如。

 提示DB`输入测试分数。不要忘记最后一个0 

atof 需要堆栈中的内存地址,并将结果返回到FPU寄存器ST(0)。

  SECTION .data 
prompt DB你必须把每一个字符串转换成一个数字。 `输入一个测试分数\\\
`,0
fmt DB%s,0
fmtf DB`Sum:%f\\\
`,0

SECTION。 bss
test1 resb 1000
test2 resb 1000
test3 resb 1000
test4 resb 1000
double1 resq 1;预留Quadword = Double
double2 resq 1
double3 resq 1
double4 resq 1
sum resq 1

SECTION .code
extern printf, scanf,atof
全局主
主:

push ebp; Prolog
mov ebp,esp

推送提示; `输入测试分数\ $`
call printf
add esp,(1 * 4); Pop 1 dword
push test1
push fmt; %s
call scanf
add esp,(2 * 4); Pop 2 dword
push test1
call atof
fstp qword [double1]
add esp,(1 * 4);流行1 dword

推送提示; `输入测试分数\ $`
call printf
add esp,(1 * 4); Pop 1 dword
push test2
push fmt; %s
call scanf
add esp,(2 * 4);流行2个单词
push test2
call atof
fstp qword [double2]
add esp,(1 * 4);流行1 dword

推送提示; `输入测试分数\ $`
call printf
add esp,(1 * 4); pop 1 dword
push test3
push fmt; %s
call scanf
add esp,(2 * 4); Pop 2 dword
push test3
call atof
fstp qword [double3]
add esp,(1 * 4);流行1 dword

推送提示; `输入测试分数\ $`
call printf
add esp,(1 * 4); Pop 1 dword
push test4
push fmt; %s
call scanf
add esp,(2 * 4); Pop 2 dword
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 dword [sum + 0]
push fmtf; `result:%f\\\
`,0
call printf
add esp,(3 * 4);流行音乐3 dwords

mov esp,ebp; Epilog
pop ebp
ret

您不需要 ATOF 。您可以让 scanf 将输入的字符串转换为格式字符串%lf。

  SECTION .data 
prompt DB`输入一个测试分数\\\
`,0
fmt DB%lf,0; scanf需要'lf'来存储双
fmtf DB`Sum:%f\\\
`,0; printf只需要'f'来打印一个double

SECTION .bss
double1 resq 1;预留Quadword = Double
double2 resq 1
double3 resq 1
double4 resq 1
sum resq 1

SECTION .code
extern printf, scanf,atof
全局主
主:

push ebp; Prolog
mov ebp,esp

推送提示; `输入测试分数\ $`
call printf
add esp,(1 * 4); Pop 1 dword
push double1
push fmt; %lf
call scanf
add esp,(2 * 4);流行2个单词

推送提示; `输入测试分数\ $`
call printf
add esp,(1 * 4); Pop 1 dword
push double2
push fmt; %lf
call scanf
add esp,(2 * 4);流行2个单词

推送提示; `输入测试分数\ $`
call printf
add esp,(1 * 4); Pop 1 dword
push double3
push fmt; %lf
call scanf
add esp,(2 * 4);流行2个单词

推送提示; `输入测试分数\ $`
call printf
add esp,(1 * 4); Pop 1 dword
push double4
push fmt; %lf
call scanf
add esp,(2 * 4); Pop 2 dword

fld qword [double1]
fadd qword [double2]
fadd qword [double3]
fadd qword [double4]
fstp qword [ sum]

push dword [sum + 4];双推两步
push dword [sum + 0]
push fmtf; `result:%f\\\
`,0
call printf
add esp,(3 * 4);流行音乐3 dwords

mov esp,ebp; Epilog
pop ebp
ret


I am having some trouble getting the c function atof() to work in my asm program. I'm trying to read in 4 numbers from the keyboard, and ultimately print their average. Before i can do that, however, i need to convert the numbers to floats. I'm stuck on successfully getting my 'total' variable to work. I have tried calling atof in multiple spots to no avail.

This is a x86 NASM program

;   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

EDIT: upon revision, i was able to turn the inputted values in their respective numeric values using these code blocks

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  

Sample run through:

./prg2b
enter a test score.
1
enter a test score.
1
enter a test score.
1
enter a test score.
1
41111

this addition to my code gets rid of my problem with the atof() call, but it is only successful if the numbers are one digit and if total is <10

If anyone could give a hint as to how to properly using atof, or how to properly convert to floating point numbers in a program that uses scanf, it would be greatly appreciated. I'm very new (read: 2 weeks of learning) to x86 asm. This is compiled in the terminal on a UNIX system

解决方案

You can define a C literal with escape sequences in NASM by using backticks. E.g.

prompt  DB  `enter a test score.\n`, 0    ; Don't forget the last 0

atof needs a memory address on the stack and returns the result in register ST(0) of the FPU. You have to convert every single string to a number before you can calculate with it.

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

You don't need atof. You can let scanf convert the inputted string with the format string " %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

这篇关于在x86 NASM中使用atof函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆