2013-12-04 2 views
0

У меня проблема с одной задачей сборки - мне нужно преобразовать простое число (с плавающей запятой) в 32-битное представление с плавающей точкой и напечатать его как четырехзначное шестнадцатеричное число.Сборка: преобразование числа в 32-разрядный

Спасибо.

+3

вы не можете сжать 32 бит в четырехзначном шестнадцатеричном номере. – Henrik

+1

Что вы пробовали? Что вам нужно для этой задачи? –

+0

Я не знаю, как начать. Поэтому я был бы благодарен за любую помощь ... –

ответ

4

Вот краткий пример синтаксиса 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