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

时间:2017-05-03 00:42:31

标签: linux assembly nasm x86-64

尝试在nasm中将float转换为十六进制

1 个答案:

答案 0 :(得分:1)

如何将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

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

hex db "0123456789F"

将每个半字节的数字解释为数组的索引([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位)的十六进制表示,表示双精度flosting点数。

相关问题