浮点数显示十六进制x86-64nasmlinux

Float point to display hexadecimal x86-64 nasm linux

正在尝试将 nasm

中的浮点数转换为十六进制

如何将 DWORD(单精度浮点数)转换为十六进制

十六进制表示法只是二进制表示法的简化。一次四位组成一个十六进制数字。

SA: dd 500.312

NASM将十进制数500.312转换成内部格式"DWORD"——一堆32位:

01000011111110100010011111110000

将它们分组为 4 位组(半字节)并将每组转换为十进制:

0100 0011 1111 1010 0010 0111 1111 0000
   4    3   15   10    2    7   15    0

获取十六进制数字的最简单方法是查找 table。字符串是构成16个十六进制字符数组的合适方式:

hex db "0123456789ABCDEF"

将每个半字节的数字解释为数组的索引([hex+index])并将其存储在要输出的字符串中。

一个挑战是从左到右隔离半字节。您可以使用 ROL,4 指令,将结果移动到另一个寄存器并用 AND 0x0F 隔离半字节。另一种方法是使用 SHLD。当您隔离了半字节后,您还有十六进制数组的索引。

示例:

BITS 64
DEFAULT rel
GLOBAL _start

SECTION .data
    SA dd 500.312               ; Single floating point number
    hex db "0123456789ABCDEF"   ; Array of 16 characters
    lf db 10                    ; New line

SECTION .bss
    outstr resb 16              ; Array of 16 unitialized bytes

SECTION .text

DWORD_to_hex:                   ; ARG: EAX: DWORD value, ESI: Pointer to an array of at least 8 bytes
    xor esi, esi                ; RSI = 0 (access to ESI clears the upper DWORD of RSI)
    mov ecx, 8                  ; RCX = 8
    .LL3:
    xor sil, sil                ; Clear lowest byte of RSI
    shld esi, eax, 4            ; Copy 4 leftmost bits from EAX to ESI
    shl eax, 4                  ; Shift EAX accordingly
    mov dl, [hex + esi]         ; Get a hexadecimal character
    mov [edi], dl               ; Store the character
    add edi, 1                  ; Increment the pointer to outstr
    loop .LL3                   ; Loop RCX times

    ret

_start:                         ; Entry point - here starts the program

    mov eax, [SA]               ; Single floating point number coded as DWORD
    mov rdi, outstr             ; OFFSET outstr
    call DWORD_to_hex

    ; Show hex (8 characters)
    mov eax, 1                  ; SYS_WRITE
    mov edi, 1                  ; STDOUT
    mov rsi, outstr             ; Message address
    mov edx, 8                  ; Number of bytes to display
    syscall                     ; Call Linux

    ; New line
    mov eax, 1                  ; SYS_WRITE
    mov rdi, 1                  ; STDOUT
    mov rsi, lf                 ; Message address
    mov edx, 1                  ; Number of bytes to display
    syscall                     ; Call Linux

    ; Exit (0)
    mov eax, 60                 ; SYS_EXIT
    mov edi, 0                  ; Exitcode
    syscall                     ; Call Linux / no return

调整这些步骤以获得表示双精度浮点数的 QWORD(64 位)的十六进制表示。