Вот краткий пример синтаксиса NASM.
- Она считывает номер в со стандартного ввода
- петли через символы
- строит целое число (характеристика) и фракции (мантиссы) отдельно
-
- Используя наивный алгоритм, где вы умножить на 10 или делить на 10 степеней десятичного разряда соответственно
- Затем он преобразует результат в шестнадцатеричные символы, используя бит s hift и таблица поиска
Я использовал регистры и функции SSE XMMx, потому что они более понятные и современные, чем инструкции FPU x87. Также вы упомянули, что процессор имеет 64 бит, поэтому он должен быть совместимым/совместимым.
Вы можете бездельничать с программой в Интернете по адресу ideone.com
http://ideone.com/Q3naVN
Прочитайте комментарии и попытаться узнать что-то.
global _start
section .data
ten dq 10.0
one dq 1.0
zero dq 0.0
negate dq 8000000000000000h
result dd 0.0
hex db '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'
length dd 0
buffer db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
section .text
_start:
;;
;; read the fp number from stdin
;;
mov ecx, buffer
mov edx, 32
call read
mov dword [length], eax
movq xmm0, qword [zero]
movq xmm1, qword [zero]
movq xmm2, qword [ten]
movq xmm4, qword [ten]
;;
;; loop through 1 character at a time
;;
mov ebx, dword [length]
test ebx, ebx
jz quit ;; there's no input
mov ecx, 0 ;; offset counter
mov edx, 0 ;; 0 for before decimal, 1 for after decimal
mov edi, 0 ;; 0 for positive, 1 for negative
mov esi, buffer
cmp byte [esi], '-'
jne process
mov edi, 1 ;; the number is negative
inc ecx
process:
movzx eax, byte [esi + ecx]
cmp al, '.' ;; does al contain a decimal point '.'
jne next_check
test edx, edx ;; more than 1 decimal error
jnz quit
mov edx, 1
jmp continue_process
next_check:
sub eax, '0' ;; ascii digit to binary
js end_process ;; not a digit since eax is negative
cmp eax, 10
jge end_process ;; not a digit since eax is >= 10
test edx, edx ;; before or after decimal
jnz mantissa_process
mulsd xmm0, xmm2 ;; result characteristic * 10
cvtsi2sd xmm3, eax
addsd xmm0, xmm3 ;; result characteristic + next digit
jmp continue_process
mantissa_process:
cvtsi2sd xmm3, eax
divsd xmm3, xmm2 ;; next digit/current mantissa power of 10
addsd xmm1, xmm3 ;; result mantissa + next fraction
mulsd xmm2, xmm4 ;; mantissa power * 10
continue_process:
inc ecx
cmp ecx, ebx
jl process
end_process:
addsd xmm0, xmm1 ;; characteristic + mantissa
test edi, edi ;; is the number supposed to be negative ?
jz store_result
movq xmm3, qword [negate]
por xmm0, xmm3 ;; toggle the sign bit
store_result:
cvtsd2ss xmm0, xmm0 ;; double (64bit) to single (32) fp
movd eax, xmm0
mov dword[result], eax
;;
;; convert result to hex
;;
to_hex:
mov edi, buffer
mov esi, hex
mov ebx, 0
mov eax, dword [result]
mov bl, al
and bl, 0fh
mov bl, byte [esi + ebx]
mov byte [edi + 7], bl
shr eax, 4
mov bl, al
and bl, 0fh
mov bl, byte [esi + ebx]
mov byte [edi + 6], bl
shr eax, 4
mov bl, al
and bl, 0fh
mov bl, byte [esi + ebx]
mov byte [edi + 5], bl
shr eax, 4
mov bl, al
and bl, 0fh
mov bl, byte [esi + ebx]
mov byte [edi + 4], bl
shr eax, 4
mov bl, al
and bl, 0fh
mov bl, byte [esi + ebx]
mov byte [edi + 3], bl
shr eax, 4
mov bl, al
and bl, 0fh
mov bl, byte [esi + ebx]
mov byte [edi + 2], bl
shr eax, 4
mov bl, al
and bl, 0fh
mov bl, byte [esi + ebx]
mov byte [edi + 1], bl
shr eax, 4
mov bl, al
and bl, 0fh
mov bl, byte [esi + ebx]
mov byte [edi + 0], bl
;;
;; print result
;;
print_dword:
mov ecx, buffer
mov edx, 8
call write
;;
;; quit
;;
quit:
call exit
exit:
mov eax, 01h ; exit()
xor ebx, ebx ; errno
int 80h
read:
mov eax, 03h ; read()
mov ebx, 00h ; stdin
int 80h
ret
write:
mov eax, 04h ; write()
mov ebx, 01h ; stdout
int 80h
ret
вы не можете сжать 32 бит в четырехзначном шестнадцатеричном номере. – Henrik
Что вы пробовали? Что вам нужно для этой задачи? –
Я не знаю, как начать. Поэтому я был бы благодарен за любую помощь ... –