如何在SASM中打印浮点数?

时间:2014-05-17 11:47:20

标签: assembly nasm

我正在使用sasm ide。我的问题是如何打印浮点数。该程序成功执行但未显示任何数字。我的代码如下:

%include "io.inc"

section .data
val: dq a123.45

section .bss
res:resq 1
section .text
global CMAIN
CMAIN:
    mov ebp, esp; for correct debugging
    ;write your code here
   fld qword[val]
 fsqrt
   fst qword[res]


     xor eax, eax
    ret 

2 个答案:

答案 0 :(得分:1)

您可以将结果的整数部分与FIST隔离开来。由于SASM没有PRINT_FLOAT宏,因此您将结果的小数部分转换为ASCIIZ字符串。这可以通过将小数部分乘以10来隔离数字来管理。结果整数是下一个十进制数字。注意舍入模式,因为FIST根据当前的舍入模式舍入整数!后续的FISUB不得产生负数。

我的建议:

%include "io.inc"

section .data
    val: dq 123.45
    ten: dd 10

section .bss
    leftdigits: resd 1
    rightdigits: resb 100
    temp: resd 1
    control_word: resw 1

section .text
global CMAIN
CMAIN:
    mov ebp, esp; for correct debugging
    ;write your code here
    fld qword[val]
    fsqrt

    ; modifying rounding mode
    fstcw [control_word]
    mov ax, [control_word]
    or ah, 0b00001100               ; rounding mode: truncating
    mov [temp], ax
    fldcw [temp]                    ; load new rounding mode

    fist dword [leftdigits]         ; store integer part
    fisub dword [leftdigits]        ; clear integer part

    ; load 10 and move it to st(1)
    fild dword [ten]
    fxch

    ; isolate digits of fractional part and store ASCII
    mov edi, rightdigits            ; pointer to ASCIIZ-buffer
    .get_fractional:
    fmul st0, st1                   ; one decimal digit into integer
    fist dword [temp]               ; store digit
    fisub dword [temp]              ; clear integer part
    mov al, byte [temp]             ; load digit
    or al, 0x30                     ; to ASCII
    mov byte [edi], al              ; store to 'rightdigits'
    add edi, 1                      ; increment pointer to string
    fxam                            ; st0 == 0.0?
    fstsw ax
    fwait
    sahf
    jnz .get_fractional             ; no: once more
    mov byte [edi], 0               ; null-termination for ASCIIZ

    ; clean up FPU
    ffree st0                       ; empty st(0)
    ffree st1                       ; empty st(1)
    fldcw [control_word]            ; restore old rounding mode

    PRINT_DEC 4, leftdigits
    PRINT_CHAR '.'                  ; decimal point
    PRINT_STRING rightdigits

    xor eax, eax
    ret

答案 1 :(得分:1)

%include "io.inc"


section .data
msg: db "Printing float number %f",0 ;format for print string
val: dq 2.45 ;64 bit floating point

section .bss
res: resq 1
section .text

global CMAIN
CMAIN:

    mov ebp, esp; for correct debugging
    ;write your code here
 fld qword[val]      ;need to convert 32 bit to 64 bit
   fstp qword[res]   ;floating load makes 80 bit
                     ;store as 64 bit
                     ;push last argument first  
  push dword[val+4] ;64 bit floating point (bottom)
   push dword[val]   ;64 bit floating point (top) 
   push dword[res+4] ;64 bit floating point (bottom)
   push dword[res]   ;64 bit floating point (top)
   push dword msg          ;adress of format string
  call printf
  add esp,20     ;pop stack
  mov eax,0          ; exit code, 0=normal
         xor eax, eax
    ret