1

我的问题是使用输入文件,其中第一个整数定义文件中有多少个整数(减去那个),然后对所有整数求和,然后找到最高和最低整数并将它们打印出来。

我的错误是找不到最高整数。我在开头用 0 实例化了 high 变量,以便它应该在第一次通过时更新,并且它永远不会被更新,但是我的最低值被发现并打印没有问题,因此我认为我的问题隐藏在我的跳跃中,但是我似乎没有任何改变,或者注释掉我的输出。这一定是一个简单的错误,但我对组装不是很熟悉,这给我带来了很多问题。

;; 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
4

1 回答 1

1

正如弗兰克科特勒所说,问题是我的低变量需要声明为一个完整的 8 个字节。我相信在访问内存时,值重叠并在该访问的内存中存储新值时更改了我的低值,但是将我的低值更改为 8 个字节解决了我的问题。

于 2013-10-24T01:56:44.540 回答