我的问题是使用输入文件,其中第一个整数定义文件中有多少个整数(减去那个整数),然后对所有整数求和,然后找到最高和最低整数并打印出来。
我的错误是找不到最高整数。我在开头用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
答案 0 :(得分:1)
正如Frank Kotler所说,问题是我的低变量需要声明为完整的8个字节。我相信在访问内存时,值是重叠的,并且在访问的内存中存储新值时更改了我的低值,但是将低值更改为8字节解决了我的问题。