Search code examples
assemblyfloating-pointx86masm32

MASM assembly - REAL4 float instructions


I'm trying to store float numbers in an array using a REAL4 data type. What are the correct instructions for the following?

  1. Getting input from user and storing in an array? For example doing this but with a REAL4 number.

    mov array[ebx], sval(input())
    
  2. Print float values. Another example,

    mov eax, array[ebx]
    print str$(eax)
    

Also if there are any links to a useful MASM real4 instruction documentation i would appreciate it, Thanks!


Solution

  • A REAL4 number is just a bunch of 32 bits like DWORD, but interpreted in a different way. If you don't need the special MASM options and checks for REAL4 you can also use the MASM types DWORD resp. SDWORD or the common assembler type DD.

    For the most external functions you have to convert a REAL4 number (Single-precision floating-point format) to a a REAL8 number (Double-precision floating-point format). The easiest way is to load the single into the FPU and store it as double.

    The input from console will be stored as a string. You have to convert this string into the desired format.

    Let's first output an array of REAL4 numbers:

    INCLUDE \masm32\include\masm32rt.inc
    
    .DATA
        result  REAL8 0.0
        array   REAL4 -1.0, 1.2, 2.3, 3.4, 4.567, 0.0
                SDWORD -1               ; End of array -> NaN
    
    .CODE
    main PROC
        xor ebx, ebx
    
        @@:
        mov eax, DWORD PTR array[ebx]   ; "DWORD PTR" = "REAL4 PTR"
        cmp eax, -1                     ; NaN = end of array?
        je @F                           ; Yes -> Jump to the next @@
    
        fld DWORD PTR array[ebx]        ; Load a single into FPU ...
        fstp QWORD PTR result           ; ... and store it as double
        printf("%f\n",result)           ; MASM32 macro that acts like the C function
    
        add ebx, 4                      ; REAL4 has 4 bytes
        jmp @B                          ; Jump to the previous @@
    
        @@:
        exit 0
    
    main ENDP
    
    END main
    

    Now let's input a couple of numbers and print them. There is place for 16 variables. The program doesn't check that limit. You end the input by typing just ENTER (without a number):

    INCLUDE \masm32\include\masm32rt.inc
    INCLUDE \masm32\macros\macros.asm
    
    .DATA
        result  REAL8 0.0
        lpstring DWORD 0
        array   REAL4 16 DUP (0.0)
                SDWORD -1                           ; End of array -> NaN
    
    .CODE
    main PROC
    
        xor ebx, ebx
    
        @@:
        mov esi, input("Enter number here ",62," ") ; Input string ... STRING!
        cmp BYTE PTR [esi], 0;                      ; Nothing inputted?
        je @F                                       ; Yes -> jump forward to the next @@
    
        push ebx                                    ; StrToFloat changes EBX! So it is to save
        INVOKE StrToFloat, esi, ADDR result         ; Convert string to double
        pop ebx                                     ; Restore the saved EBX
    
        fld REAL8 PTR result                        ; Load a double ...
        fstp REAL4 PTR array[ebx]                   ; ... and save it as single
        mov eax, -1                                 ; NaN = end of array
        mov DWORD PTR array[ebx+4], eax             ; Store the NaN as the next element
    
        add ebx, 4                                  ; Pointer to the next REAL4 in array
        jmp @B                                      ; Jump back to the previous @@
    
        @@:
        xor ebx, ebx
    
        @@:
        mov eax, DWORD PTR array[ebx]               ; "DWORD PTR" = "REAL4 PTR"
        cmp eax, -1                                 ; NaN = end of array?
        je @F                                       ; Yes -> Jump to the next @@
    
        fld DWORD PTR array[ebx]                    ; Load a single into FPU ...
        fstp QWORD PTR result                       ; ... and store it as double
        printf("%f\n",result)                       ; MASM32 macro that acts like the C function
    
        add ebx, 4                                  ; REAL4 has 4 bytes
        jmp @B                                      ; Jump to the previous @@
    
        @@:
    
        exit 0
    
    main ENDP
    
    END main