Assembly - Получено исключение с плавающей точкой

Я пытаюсь написать программу, которая рассчитывает время загрузки, но я получаю сообщение об ошибке "Исключение с плавающей запятой" при выводе. Любая помощь приветствуется, так как я пытался отладить этот код в течение достаточно долгого времени и просто не могу определить проблему. После некоторого исследования я считаю, что проблема заключается в том, где происходит деление, потому что частное не может вписаться в регистр eax, но это насколько я получил.

%include "asm_io.inc"
segment .data 
prompt1         db  "Enter the unit for file size: ", 0
prompt2         db  "Enter the unit for throughput: ", 0
prompt3         db  "Enter the file size: ", 0
prompt4         db  "Enter the througput: ", 0
outputformat    db  "The time would be %d seconds.", 10, 0

segment .bss 

segment .text
    global  asm_main
    extern printf
asm_main:
    enter   0,0               ; setup routine
    pusha
;***************CODE STARTS HERE***************************
mov eax, prompt1            ; move prompt1 into eax for display
call    print_string            ; display prompt 1
call    read_char           ; read file size unit from user
call    read_char
push    eax             ; store file size unit on stack @ ebp+20

mov eax, prompt2            ; move prompt2 into eax for display
call    print_string            ; display prompt 2
call    read_char           ; read  throughput unit from user
call    read_char
push    eax             ; store throughput unit on stack @ ebp+16

mov eax, prompt3            ; move prompt3 into eax for display
call    print_string            ; display prompt 3
call    read_int            ; read file size from user
push    eax             ; store file size on stack @ ebp+12

mov eax, prompt4            ; move prompt4 into eax for display
call    print_string            ; display prompt4
call    read_int            ; read throughput from user
push    eax             ; store throughput unit on stack @ ebp+8

call    dl_time             ; call custom function to calc download time
add esp, 16             ; remove parameters from stack

push    eax             ; push download time onto stack for printf
push    outputformat            ; push format for printf function onto stack

call    printf              ; display formatted output
add esp, 8

;***************CODE ENDS HERE*****************************
    popa
    mov     eax, 0            ; return back to C
    leave                     
    ret

; function dl_time
; returns the download time for given file
; unisnged int dl_time( char fs_unit, char speed_unit, int file_size, int        conn_speed)
; parameters:
;   fs_unit     - unit for file size
;   tp_unit     - unit for connection speed
;   file_size   - file size
;   throughput  - connection speed
; return value:
;   download time for given file with given speed, in seconds floored

%define fs_unit     [ebp+20]
%define tp_unit     [ebp+16]
%define file_size   [ebp+12]
%define throughput  [ebp+8]

dl_time:
    enter   0,0             ; make room for speed and size on stack
    push    ebx             ; store value of ebx
    push    ecx             ; store value of ecx
    push    edx             ; store value of edx

    mov edx, 'B'
    cmp edx, fs_unit            ; if file size unit is byte
    jz  fs_B

    mov edx, 'K'
    cmp edx, fs_unit            ; if file size unit is kilobyte
    jz  fs_K

    mov edx, 'M'
    cmp edx, fs_unit            ; if file size unit it megabyte
    jz  fs_M

fs_B:
    ;imul   eax, file_size, 1024        ; calculate file size in bits
    sal file_size, 10
    jmp after_fs
fs_K:
    ;imul   eax, file_size, 1024
    ;imul   eax, 1024           ; calculate file size in bits
    sal file_size, 20
    jmp after_fs
fs_M:
    ;imul   eax, file_size, 1024
    ;imul   eax, 1024
    ;imul   eax, 1024           ; calculate file size in bits
    sal file_size, 30

after_fs:
    mov edx, 'B'
    cmp edx, tp_unit            ; if throughput unit is bits per second
    jz  after_tp

    mov edx, 'K'
    cmp edx, tp_unit            ; if throughput unit is kilobits per second
    jz  tp_K

    mov edx, 'M'
    cmp edx, tp_unit            ; if throughput unit is megabits per second
    jz  tp_M

tp_K:
    ;imul   ebx, throughput, 1024       ; convert kilobits to bits
    sal throughput, 10
    jmp after_tp
tp_M:
    ;imul   ebx, throughput, 1024       ; convert megabits to bits
    ;imul   ebx, 1024
    sal throughput, 20

after_tp:
    xor edx, edx            ; clear edx for division
    mov eax, file_size
    mov ebx, throughput
    div ebx             ; divide file size by throughput
    mov ecx, 128            ; move 128 into ecx for division
    div ecx             ; divide quotient by 128 to arive at download time

pop ebx
pop ecx
pop edx
leave
ret

Спасибо

1 ответ

Вы не очищаете edx перед вторым делением:

div ebx             ; divide file size by throughput
; EDX WILL NOW BE SET TO EAX % EBX (I.E. THE REMAINDER)
mov ecx, 128            ; move 128 into ecx for division
; THERE SHOULD BE AN XOR EDX,EDX HERE
div ecx             ; divide quotient by 128 to arive at download time
Другие вопросы по тегам