2015-07-23 2 views
0

Я пытаюсь написать программу, которая вычисляет время загрузки, но я продолжаю получать ошибку вывода с плавающей запятой на выходе. Любая помощь приветствуется, поскольку я пытался отладить этот код довольно долго и просто не могу определить проблему. После некоторых исследований я считаю, что проблема заключается в том, где происходит разделение, потому что фактор не может вписаться в регистр 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 

Спасибо

+0

Вы можете использовать отладчик для пошагового ваш код, и посмотреть, что в регистрах до исключение. http://stackoverflow.com/tags/x86/info –

ответ

0

Вы не очищая 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 
+0

Благодарим вас за это. Я обнаружил, что корень проблемы в моей логике переключения. Когда я меняю file_size более 7 бит, значение EAX становится 0. Я не уверен, как обеспечить, чтобы file_size было двойным словом перед переключением. –

Смежные вопросы