【问题标题】:MASM assembly - REAL4 float instructionsMASM 汇编 - REAL4 浮点指令
【发布时间】:2017-12-24 02:07:52
【问题描述】:

我正在尝试使用 REAL4 数据类型将浮点数存储在数组中。以下正确的说明是什么?

  1. 从用户那里获取输入并存储在一个数组中?例如这样做但使用 REAL4 数字。

    mov array[ebx], sval(input())
    
  2. 打印浮点值。另一个例子,

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

另外,如果有任何指向有用的 MASM real4 说明文档的链接,我将不胜感激,谢谢!

【问题讨论】:

  • 没有print 指令。您必须调用一个函数来打印任何内容(或自己编写代码以转换为字符串)。请注意printf 仅适用于double,因此您可能需要cvtss2sd xmm1, array[ebx]
  • @PeterCordes: print 是一个包含在 MASM32 包中的宏。

标签: assembly floating-point x86 masm32


【解决方案1】:

REAL4 数字只是一堆 32 位,如 DWORD,但以不同的方式解释。如果您不需要特殊的 MASM 选项并检查 REAL4,您也可以使用 MASM 类型的 DWORD 。 SDWORD 或通用汇编类型 DD。

对于大多数外部函数,您必须将 REAL4 数字(单精度浮点格式)转换为 REAL8 数字(双精度浮点格式)。最简单的方法是将单曲加载到 FPU 中并将其存储为双曲。

来自控制台的输入将被存储为一个字符串。您必须将此字符串转换为所需的格式。

让我们先输出一个 REAL4 数的数组:

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

现在让我们输入几个数字并打印出来。有 16 个变量的位置。该程序不检查该限制。您只需键入 ENTER(不带数字)即可结束输入:

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

【讨论】:

  • 对于可变参数函数,您只需转换为double。大多数 C 库数学函数都有一个f-suffix 版本,它接受并返回一个float。例如sqrtfsinfatan2f。我假设 MSVC 的标准库提供了这些。另外,我不建议先使用/学习 x87。即使在 32 位代码中,假设支持 SSE / SSE2 也很常见。如果您使用在st(0) 中返回 FP 值的调用约定,则只需使用 x87。
猜你喜欢
  • 1970-01-01
  • 2020-02-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-02-27
  • 2011-11-22
相关资源
最近更新 更多