尝试在nasm中将float转换为十六进制
答案 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点数。