News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

need help with comparing char's...

Started by Taelor, November 21, 2005, 12:26:39 PM

Previous topic - Next topic

Taelor

ok first off let me tell you...YES, this part of my homework assignment. but before you kick me out, lemme remind you i have spent mucho time on this problem and my question is simple and is very minimal compared to the rest of the work...

in a sub routine call readInteger im supposed to read from a file, parse it, and extract the integers. they are in character format and i must return them as two's complement. my problem is comparing symbols and digits. here's the code, ill point out the problem area. oh btw, making the byte minusSign and so on is something i just tried, before i was using the ASCII values of 43, 45, and 30h, 39h respectfully. i know the buffer is filled correctly because i can use a writeString callĀ  that print out the file to the screen exactly as it looks in the file.

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; arg1: offset of file structure
; arg2: offset of where the interger being parsed

include irvine32.inc

.data

   fileHandle    dword ?
   bufferAddr   dword ?      ;+4
   maxBytes   dword ?      ;+8
   bytesRead   dword ?      ;+12

   negNum      byte  ?
   inNum      byte  ?
   
   check      byte  "return hit!", 0
   minusSign   byte  "-", 0
   plusSign   byte  "+", 0
   zero      byte  "0", 0
   nine      byte  "9", 0

.code

readInteger  proc

   push ebp
      mov ebp, esp
      pushad
   
   mov eax, 0
   mov negNum, 0
   mov inNum, 0

   mov esi, [ebp+8]
   mov edx, [esi]
   mov fileHandle, edx
   add esi, 4
   mov edx, [esi]
   mov bufferAddr, edx
   add esi, 4
   mov edx, [esi]
   mov maxBytes, edx
   mov ecx, [esi+12]
   mov ebx, [esi+16]
   mov esi, bufferAddr
   
checkEmptyBuffer:
   cmp ecx, 0
   jne processNextByte

   push eax
   
   invoke readFile,
      fileHandle, bufferAddr, maxBytes, ADDR bytesRead, 0
   
   pop eax
   
   mov ecx, bytesRead
   mov ebx, 0

   cmp ecx, 0
   jne processNextByte
   jmp endOfFile

processNextByte:
   
   add esi, ebx   
   mov edx, offset minusSign <---problem area
   mov edi, [edx]
   cmp [esi], edx
   jne checkPos
   mov negNum, 1
   mov inNum, 1
   add ebx, 1
   jmp checkEmptyBuffer
      
checkPos:
   
   add esi, ebx
   mov edx, offset plusSign <---problem area
   mov edi, [edx]
   cmp [esi], edx
   jne checkDigit
   mov negNum, 0
   mov inNum, 1
   add ebx, 1
   jmp checkEmptyBuffer
   
checkDigit:
   
   add esi, ebx
   mov edx, offset zero <---problem area
   mov edi, [edx]
   cmp [esi], edx
   jl notDigit
   mov edx, offset nine <---problem area
   mov edi, [edx]
   cmp [esi], edx
   jg notDigit
   mov inNum, 1
   mov edx, 10
   imul edx
   add eax,[esi]
   add ebx, 1
   jmp checkEmptyBuffer

notDigit:

   cmp inNum, 1
   jne notDone
   cmp negNum, 1
   jne notNeg
   neg eax
   jmp return

notNeg:
   jmp return

notDone:
   add ebx, 1
   jmp checkEmptyBuffer

endOfFile:


return:
   mov edx, 0
   mov edx, offset check
   call writeString
   call crlf

   mov esi, [ebp+8]
   add esi, 12
   mov [esi], ecx
   add esi, 4
   mov [esi], ebx
   mov edx, [ebp + 12]
   mov [edx], eax
   popad
   pop ebp
   ret 8

readInteger endp

end

yes, dont feel obliged to help if you think im cheating. i just need some help. trust me, i dont get up at 6:30 in the morn to work on Assembly. this is one of those all night kinda things....

Jimg

First off, it looks like you are not picking up the input parameters correctly-

mov esi, [ebp+8]          ; ok, first parameter, file handle
   mov edx, [esi]
   mov fileHandle, edx

   add esi, 4
   mov edx, [esi]            ; ok, second parameter, this would be [ebp+12]
   mov bufferAddr, edx
   add esi, 4                  ; ok, third parameter, this would be [ebp+16]
   mov edx, [esi]
   mov maxBytes, edx

   mov ecx, [esi+12]      ; you've already added 8 to esi, so this would be [ebp+28], parameter 6, is there was one
   mov ebx, [esi+16]     ; and this would be parameter 7

so ecx is not the count of bytes, and may be zero, it probably isn't, which would skip the readFile and you would just be processing garbage that happened to be at the input buffer location.  And ebx is definately not correct.  I think you just want to set ecx to zero at this point so it read the file.



Now to the processing-

processNextByte:
   
   add esi, ebx   
   mov edx, offset minusSign <---problem area
   mov edi, [edx]
   cmp [esi], edx
   jne checkPos
   mov negNum, 1

when you do a move edi,[edx], it moves a dword, or 4 bytes, not a single character to compare, so your comparison will always be incorrect.

the correct way, trying the use the registers as you have them set up, is to

   cmp [esi], byte ptr '-'    ; compare byte at location to a minus sign.

another way is to move the byte to a byte size register and test it-

mov al,[esi]
cmp al,'-'


This assumes that esi is correctly pointing to the byte you want to test, which I don't think it is.  It looks like you are not restoriong esi after adding ebx to it for the next time through the loop.  Without just telling you how to do it, I think you need to start over and Keep It Simple ...

For example, just use one register to pick up the byte to test, and increment it each time through the loop.  No need to use both esi and ebx.

Taelor

Quote from: Jimg on November 21, 2005, 03:06:21 PM
First off, it looks like you are not picking up the input parameters correctly-

mov esi, [ebp+8] ; ok, first parameter, file handle
mov edx, [esi]
mov fileHandle, edx

add esi, 4
mov edx, [esi] ; ok, second parameter, this would be [ebp+12]
mov bufferAddr, edx
add esi, 4 ; ok, third parameter, this would be [ebp+16]
mov edx, [esi]
mov maxBytes, edx

mov ecx, [esi+12] ; you've already added 8 to esi, so this would be [ebp+28], parameter 6, is there was one
mov ebx, [esi+16] ; and this would be parameter 7

so ecx is not the count of bytes, and may be zero, it probably isn't, which would skip the readFile and you would just be processing garbage that happened to be at the input buffer location. And ebx is definately not correct. I think you just want to set ecx to zero at this point so it read the file.

lemme explain what im doing here. there is a filestructure being sent in. thats the first parameter fileHandle. now with the address of the fileHandle, you can access the bufferAddr, then maxBytes, and then numBytes (the amount of bytes left to scan, which is set by bytesRead), and nextChar is the pointer to the next character in the Buffer. this is how its set up in the main program.

align 4
fileStructure label dword
   fileHandle   dword ?
   bufferAddr   dword ?      ;+4
   maxBytes   dword ?      ;+8
   bytesRead   dword ?      ;+12
   nextChar   dword ?      ;+16


and now for your other help....yes esi, gets the bufferAddr sent to it, thats tested and correct i know for sure 100%. ebx gets incremented by one to move down the buffer. And i feel stupid for not remembering to use a byte register instead of a full 32-bit one. but i like the ptr "-" way, looks fancier. thanks for the help, and do you get what im doing with the fileStructure?