汇编浮点数运算

huangapple go评论58阅读模式
英文:

Assembly floating point math

问题

我正在制作一个编译器,它编译成x86_64汇编语言,并尝试实现浮点数运算。然而,我很快遇到了问题,因为在汇编中使用浮点数很困难,所以我试图练习它们,但是我没有找到成功的方法。

在这个程序中,我想将两个浮点数相加,将它们与另一个浮点数进行比较,并在它们相等时打印一条消息,但是没有任何内容被打印出来。

section .data
    float1: dd 3.14
    float2: dd 5.72
    cmp_float: dd 8.86
    msg: db "Is equal!", 10, 0
    msg_len equ $-msg

section .bss
    result: resd 1

section .text
    global _start

_start:
    fld dword [float1]  ; 将float1加载到FPU堆栈中
    fld dword [float2]  ; 将float2加载到FPU堆栈中
    faddp               ; 将FPU堆栈的前两个浮点数相加,并将结果推回到FPU堆栈中

    fcomp dword [cmp_float] ; 与FPU堆栈中的顶部值进行比较

    fstsw ax            ; 将FPU状态字存储在AX寄存器中
    sahf                ; 将AH寄存器的值移动到FLAGS寄存器中

    je .equal
    jmp .exit
.equal:
    mov rax, 1
    mov rdi, 1
    mov rsi, msg
    mov rdx, msg_len
    syscall
.exit:
    mov rax, 60
    mov rdi, 0
    syscall

请注意,这是你提供的汇编代码的翻译部分。

英文:

I am making a compiler that compiles to x86_64 assembly, and I am trying to implement floating point math. However, I soon ran into problems because floating points are a struggle in assembly, so I am trying to practice with them, but I am finding no luck.

In this program, I want to add two floats together, compare them with another float and print a message if they are equal, but nothing is being printed.

section .data
	float1: dd 3.14
	float2: dd 5.72
	cmp_float: dd 8.86
	msg: db "Is equal!", 10, 0
	msg_len equ $-msg

section .bss
	result: resd 1

section .text
	global _start

_start:
	fld dword [float1]  ; Load float1 into FPU stack
	fld dword [float2]  ; Load float2 into FPU stack
	faddp               ; Add two top floats of the FPU stack and push back onto the FPU stack

	fcomp dword [cmp_float] ; Compare with the top value of the FPU stack

    fstsw ax            ; Store FPU status word in AX register
    sahf                ; Move AH register to FLAGS register

	je .equal
	jmp .exit
.equal:
	mov rax, 1
	mov rdi, 1
	mov rsi, msg
	mov rdx, msg_len
	syscall
.exit:
	mov rax, 60
	mov rdi, 0
	syscall

答案1

得分: 0

我不了解x87和一切,谢谢@Jester,而是使用由SSE(流式SIMD扩展)或AVX(高级矢量扩展)指令集提供的SIMD(单指令,多数据)指令:

section .data
    number1 dd 2.5          ; 第一个浮点数
    number2 dd 1.3          ; 第二个浮点数
    result_add dd 0.0       ; 用于存储加法结果的变量
    result_sub dd 0.0       ; 用于存储减法结果的变量
    result_mul dd 0.0       ; 用于存储乘法结果的变量
    result_div dd 0.0       ; 用于存储除法结果的变量

section .text
    global _start

_start:
    ; 加法
    movss xmm0, [number1]       ; 将number1加载到xmm0
    movss xmm1, [number2]       ; 将number2加载到xmm1
    addss xmm0, xmm1             ; 将xmm1加到xmm0
    movss [result_add], xmm0    ; 存储结果

    ; 减法
    movss xmm0, [number1]       ; 将number1加载到xmm0
    movss xmm1, [number2]       ; 将number2加载到xmm1
    subss xmm0, xmm1             ; 从xmm0减去xmm1
    movss [result_sub], xmm0    ; 存储结果

    ; 乘法
    movss xmm0, [number1]       ; 将number1加载到xmm0
    movss xmm1, [number2]       ; 将number2加载到xmm1
    mulss xmm0, xmm1             ; 将xmm0与xmm1相乘
    movss [result_mul], xmm0    ; 存储结果

    ; 除法
    movss xmm0, [number1]       ; 将number1加载到xmm0
    movss xmm1, [number2]       ; 将number2加载到xmm1
    divss xmm0, xmm1             ; 将xmm0除以xmm1
    movss [result_div], xmm0    ; 存储结果

    ; ... 你的代码的其余部分

    ; 退出程序
    mov rax, 60
    mov rdi, 0
    syscall
英文:

I didn't know about x87 and everything, thank you @Jester, instead use SIMD (Single Instruction, Multiple Data) instructions provided by the SSE (Streaming SIMD Extensions) or AVX (Advanced Vector Extensions) instruction sets:

section .data
    number1 dd 2.5          ; First floating-point number
    number2 dd 1.3          ; Second floating-point number
    result_add dd 0.0       ; Variable to store the addition result
    result_sub dd 0.0       ; Variable to store the subtraction result
    result_mul dd 0.0       ; Variable to store the multiplication result
    result_div dd 0.0       ; Variable to store the division result

section .text
    global _start

_start:
    ; Addition
    movss xmm0, [number1]       ; Load number1 into xmm0
    movss xmm1, [number2]       ; Load number2 into xmm1
    addss xmm0, xmm1             ; Add xmm1 to xmm0
    movss [result_add], xmm0    ; Store the result

    ; Subtraction
    movss xmm0, [number1]       ; Load number1 into xmm0
    movss xmm1, [number2]       ; Load number2 into xmm1
    subss xmm0, xmm1             ; Subtract xmm1 from xmm0
    movss [result_sub], xmm0    ; Store the result

    ; Multiplication
    movss xmm0, [number1]       ; Load number1 into xmm0
    movss xmm1, [number2]       ; Load number2 into xmm1
    mulss xmm0, xmm1             ; Multiply xmm0 by xmm1
    movss [result_mul], xmm0    ; Store the result

    ; Division
    movss xmm0, [number1]       ; Load number1 into xmm0
    movss xmm1, [number2]       ; Load number2 into xmm1
    divss xmm0, xmm1             ; Divide xmm0 by xmm1
    movss [result_div], xmm0    ; Store the result

    ; ... Rest of your code

    ; Exit the program
    mov rax, 60
    mov rdi, 0
    syscall

huangapple
  • 本文由 发表于 2023年6月22日 03:33:05
  • 转载请务必保留本文链接:https://go.coder-hub.com/76526572.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定