2013-10-16 68 views
1

這裏我的問題是,使用輸入文件,其中第一個整數定義文件中有多少個整數(減去那個),然後求和所有整數,然後找到最高和最低整數並打印出來。assembly find min max values

我的錯誤是沒有找到最高的整數。我在0開始時初始化高變量,以便它在第一遍時更新,並且它不會被更新,但是我的最低值被發現和打印沒有問題,因此我假設我的問題隱藏在我的跳躍中,但是我似乎沒有改變,或者註釋掉我的輸出。這肯定是一個簡單的錯誤,但我對組裝並不是很熟悉,它給我帶來了很多問題。

;; NASM program to read from cmd line arg, open file, read first line, and print first line to screen 
;; Uses fopen, fscanf, and printf 
;; For help using the stack to write subroutines, consult the assembly lecture "Stack Basics and Procedure Calls" 

;; nasm -f elf cfunctions.asm 
;; gcc -o output cfunctions.o -m32 
;; output input.txt 


%include "mine.inc" 

extern printf 
extern fopen 
extern sscanf 
extern fscanf 

%define STDIN 0 
%define STDOUT 1 
%define SYSCALL_EXIT 1 
%define SYSCALL_READ 3 
%define SYSCALL_WRITE 4 


global main 

section .data 

read_char: db 'r', 0 
format:  db "%d",10,0 
filename: dd 0 
file_pointer: dd 0 
number:  dd 0 
string:   db "The integer is %d",10,0 
sumString: db "The sum is %d",10,0 
lowString: db "The lowest number is %d",10,0 
highString: db "The highest number is %d",10,0 

section .bss 

    temp resb 8; reserves a lot for the manipulated item 
    low: resb 2 ; reserves 2 bytes buffer for low, because if theres a low under 65k i'll be so mad!! 
    high: resb 8; reserves a lot for a big number 
    sum: resb 8 ; reserves a lot for the sum 
    size: resb 2; only need a word for ints 1000 (hopefully) 


section .text 

main: 

    ; instatiate the min and max values 
    mov eax, 65535 
    mov [low], eax ; starts the low really high 
    xor eax,eax; sets eax to zero 
    mov [high], eax ; high is now zero 

    ;; Get the filename, pointer to input filename is returned, will equal 0 for an invalid filname 
    push dword filename ; Push address of the pointer to the filename 
    call GetCommandLine ; Return address pushed to stack, Go to line 72, GetCommandLine 
add esp, 4  ; Resets stack value (equivalent to 'pop' inst) 

;; (You need to insert code here to error check filename) 

;; Open the file using fopen 
;; Equivalent to eax = fopen("input.txt", "r") if programmed in C 
push dword read_char ; "r" to open a file for reading 
push dword [filename] ; filename from cmd line arg 
call fopen 
add  esp, 8 

;; Error check fstream returned from fopen 
cmp eax, 0 
je Exit 
mov [file_pointer], eax 

;; Read a value from the file using fscanf 
push  dword number ; Address of 'number' 
push dword format ; %d to read an integer 
push dword [file_pointer] ; fstream from fopen 
call fscanf 
add  esp, 12 

    mov ecx, [number] ; 
    mov [size], ecx ; 

    xor ecx, ecx 

loopFile: 

    ;; Read a value from the file using fscanf 
     push dword number ; Address of 'number' 
    push dword format ; %d to read an integer 
    push dword [file_pointer] ; fstream from fopen 
    call fscanf 
    add  esp, 12 

    ;; sum is calculated here 
    mov eax, [number] 
    mov [temp], eax ; temp is now the current number from the file 
    add [sum], eax ; 


    ;; lowest is calculated here 
    mov ebx, eax;[temp] 
    mov ecx, [low] 
    cmp ebx,ecx ; compares if temp is less than lowest 
    jl lessThan 

    jmp highest ; test2 maybe it's not jumping 

highest: ;; higest is calculated here 
    mov ebx, eax; [temp] 
    mov ecx, [high] 
    cmp ebx,ecx 
    jg higherThan 

    jmp count ; test2 

;; Print every int in the file 
count: 
    push dword [number] 
    push dword string 
    call printf 
    add  esp, 8 

;count: 
;counter of how many ints left 
    mov ecx, [size]; moves into ecx 
    dec ecx ; decreminte ecx 
    mov [size], ecx ; 

    cmp ecx, 0; 
    jg loopFile ; jumps to the beginining of the loop 

    ;; prints the sum 
    push dword [sum] 
    push dword sumString 
    call printf 
    add esp,8 

    ;; prints the lowest 
    push dword [low] 
    push dword lowString 
    call printf 
    add esp,8 

    ;;prints the highest 
    push dword [high] 
    push dword highString 
    call printf 
    add esp,8 



Exit: 
    mov  EAX, SYSCALL_EXIT 
     mov  EBX, 0 
     int  080h 
    ret 

lessThan: 
    mov ebx, [temp] 
    ;mov ecx, [low] 
    ;mov ecx, ebx 
    mov [low], ebx ; moves lowest into low 
    jmp highest ; jumps to next comparison 

higherThan: 
    mov ebx, [temp] 
    ;mov ecx, [high] 
    ;mov ecx,ebx 
    mov [high], ebx ; moves highest into high 
    jmp count 

GetCommandLine: 

;; Macros to move esp into ebp and push regs to be saved 
     Enter 0 
     Push_Regs ebx, ecx, edx 

;; Initially sets [filename] to 0, remains 0 if there's an error 
     mov ebx, [ebp + 8] 
     mov [ebx], dword 0 

;; Get argc (# of arguments) 
     mov ecx, [ebp + 16] 

;; Checks the value of argc, should be 2 (a.out and input.txt), includes the if statement macro 
    cmp ecx, 2 
    if ne 
     jmp gcl_done 
    endif 

;; Get argv[0] ("a.out"/"cfunctions" or the executable, this is not used in the project) 
;; Consult slide 6 of Stack Basics... lecture 
mov ecx, [ebp + 20] ; ptr to args ptr 
mov ebx, [ecx]  ; argv[0] 

;; Get argv[1] ("input.txt") 
    mov ecx, [ebp + 20] ; ptr to args ptr 
    mov ebx, [ecx + 4] ; argv[1] 

;; Set the filename pointer arg on the stack to the address of the filename 
    mov edx, [ebp + 8] 
    mov [edx], ebx 

gcl_done: 
;; Macros to return 
    Pop_Regs ebx, ecx, edx 
    Leave 

;; Return 
    ret 
+2

您的'low'變量太小。使它成爲一個雙字。 –

回答

1

正如弗蘭克科特勒提到的,問題是我的低變量需要聲明爲一個完整的8字節。我相信在訪問內存時,值會重疊,並在存儲新值時更改低值,但將低位更改爲8字節可解決我的問題。

+0

你可以通過點擊綠色的勾號來接受你自己的答案.... –