does anyone know? im using this for a file compare program im making. im still learning and this is my first time working with opening files and comparing them.
Compare_Strings proc Strin:DWORD,Strin2:DWORD
mov eax,Strin
mov ebx,Strin2
xor ecx,ecx
cmp eax,0
je Different
cmp ebx,0
je Different
Continue:
inc eax
inc ecx
inc ebx
cmp eax,0
je Equal
cmp eax,ebx
je Continue
Different:
movzx eax,al
push dword ptr
push LB_ADDSTRING
push 1002
push 1000
call SendDlgItemMessage
movzx ebx,bl
push dword ptr
push LB_ADDSTRING
push 1003
push 1000
call SendDlgItemMessage
Equal:
ret
Compare_Strings endp
Compare_Strings proc Strin:DWORD,Strin2:DWORD
mov eax,Strin
mov ebx,Strin2
xor ecx,ecx
cmp eax,0
je Different
cmp ebx,0
je Different
Continue:
inc eax
inc ecx
inc ebx
cmp eax,0
je Equal
cmp eax,ebx
je Continue
Different:
movzx eax,al
push dword ptr
push LB_ADDSTRING
push 1002
push 1000
call SendDlgItemMessage
movzx ebx,bl
push dword ptr
push LB_ADDSTRING
push 1003
push 1000
call SendDlgItemMessage
Equal:
ret
Compare_Strings endp
Compare_Strings proc Strin:DWORD,Strin2:DWORD
push ebx ;best to preserve this register
mov eax,Strin
mov ebx,Strin2
@@:
mov cl, [eax]
inc eax
cmp [ebx], cl
jnz Different
inc ebx
test cl, cl
jnz @B
Equal:
;...
Different:
;...
;xor ecx,ecx
;cmp eax,0
;je Different
;cmp ebx,0
;je Different
;Continue:
;inc eax
;inc ecx
;inc ebx
;cmp eax,0
;je Equal
;cmp eax,ebx
;je Continue
pop ebx
ret
Compare_Strings endp
I don't understand what you are doing btw...
Hexen, what you are trying in principle is ok, you have the idea.
Dont know if a post to you where deleted by the thing that happend.
A number inside a register is only a number. You can manipulate this numbers, with the arithmetic instructions, logic ones, etc, but also there is a not considered diferent branch of manipulation, and this is:
the number inside a register can be used for reference the content of the number (address) in the register, with [ and ] operators.
The things that I remark with red are the things that I consider to be uncorrect: first you move the address (masm sintaxis cant understand it completely), also you set up ecx to 0 (pheraphs first byte regarding the address of eax and ebx) then you compare the address against 0, and if is equal the strings are equal?, also when you increment eax and ebx, you are incrementing the number or the next accesible address, but you never are getting the number at that address, with [ and ], and thus, this code is never comparing the string, or content in the address against the other, like I see is a comparation about the address of the two strings, and this code only stop when one of the registers is zero. Try follow the example that roticv give you, see that he uses the [ and ] operators, for get the content at the number of the register.
Dont know if a post to you where deleted by the thing that happend.
A number inside a register is only a number. You can manipulate this numbers, with the arithmetic instructions, logic ones, etc, but also there is a not considered diferent branch of manipulation, and this is:
the number inside a register can be used for reference the content of the number (address) in the register, with [ and ] operators.
The things that I remark with red are the things that I consider to be uncorrect: first you move the address (masm sintaxis cant understand it completely), also you set up ecx to 0 (pheraphs first byte regarding the address of eax and ebx) then you compare the address against 0, and if is equal the strings are equal?, also when you increment eax and ebx, you are incrementing the number or the next accesible address, but you never are getting the number at that address, with [ and ], and thus, this code is never comparing the string, or content in the address against the other, like I see is a comparation about the address of the two strings, and this code only stop when one of the registers is zero. Try follow the example that roticv give you, see that he uses the [ and ] operators, for get the content at the number of the register.
Compare_Strings proc Strin:DWORD,Strin2:DWORD
mov eax,Strin
mov ebx,Strin2
xor ecx,ecx
cmp eax,0 je Different
cmp ebx,0
je Different
Continue:
inc eax
inc ecx
inc ebx
cmp eax,0
je Equal
cmp eax,ebx
je Continue
Different:
movzx eax,al
push dword ptr
push LB_ADDSTRING
push 1002
push 1000
call SendDlgItemMessage
movzx ebx,bl
push dword ptr
push LB_ADDSTRING
push 1003
push 1000
call SendDlgItemMessage
Equal:
ret
Compare_Strings endp
mov eax,Strin
mov ebx,Strin2
xor ecx,ecx
cmp eax,0 je Different
cmp ebx,0
je Different
Continue:
inc eax
inc ecx
inc ebx
cmp eax,0
je Equal
cmp eax,ebx
je Continue
Different:
movzx eax,al
push dword ptr
push LB_ADDSTRING
push 1002
push 1000
call SendDlgItemMessage
movzx ebx,bl
push dword ptr
push LB_ADDSTRING
push 1003
push 1000
call SendDlgItemMessage
Equal:
ret
Compare_Strings endp
thanks for your help ill look at these two examples and try to figure it out. but first i have another question how do i compare the bytes if i can't do something like this: cmp byte ptr ,byte ptr
I was searching and dont found some of the post when you talk about strings.
Anyway I will mess you with my personals points of views, hope I dont miss you.
We do operations over memory, the memory can remember. Operations cant remember the previous state or the anterior source, but they "remember" how to do the operation (the process), because a "+" always can add two numbers, and in fact, the remembering is done inside the paths of execution of the processor, the processor can remember or follow the necesary paths for do the operation.
The ram memory have addresses, and inside or the content of each address is one byte, and this value can be readed or writed using [ and ] , depending if is source or destiny.
The registers (taked like memory), dosent have a address then you cannot obtain the addresses, but you can obtain/write the content of the address with his respective name: eax, ebx, esp, mmx1, mmx2, ... . Without the necesity of have the address of eax register and use [ and ] for read or write the content of the memory, only use the name and you can read/write the content.
The registers in the point of view of the operations only "see" a "number" inside each one.
But a important thing to note is that addresses of the ram memory can also have a representative name, because this address are only numbers or offsets, we use names for name a number address, like we do in math: 1 is one or *, 2 is two or **, ... ; but we give descriptive names normally: str1, str2, hWnd, ps, wc, etc.
When you move a name of RAM memory to another register or other memory, you actually are moving the address (number) to the destination. examples:
This instructions have the same impact, you are modificating the content of memory first in the registers and then in the RAM.
When you move a address inside a register, you can add, substracts, andit, and all the operations, because the point of view of operations, but this operations are doing it to the number representing the address moved in, and for refer to the content of a number, you use [ and ] (with masm you should add two more words).
If you only whant to move 10 bytes above the a address dosent matter what contain or represent this address:
mov eax, nameOfAddress
add eax, 10
For example, you whant modify 5 continuos content of memory, add 1 dosent matter what mean that contents.
You only whant to test if a memory is a number?, regarding if the number is 'a', 9, 'hi', etc?, only need be the same size against the size (number of bytes) that you are comparing against.
number represent 'a', '9', 4, a mask of bits, or any other inmediate number
size represent byte, word, dword, the number of bytes to take for comparation, if the other operand is a register, the size of the register is tacked automatically, and is for that, in the optional place is marked with orange.
mov eax, addressName
jmp firstTest
.again:
.add eax, size
.firstTest:
..cmp size, number
..jne again
I only write the dots for keep a little the format.....
If you only whant to get/write a content of memory you use []
mov eax,
mov eax, ebx
this two move the content in memory to eax register, but remember that with registers, you dont have to use [] and because you dont know the address.
By the end note:
--addr 101-- number1 db 0x4C
01001100
--addr 102-- number2 dw 0x0770
00000111
--addr 103--
01110000
--addr 104-- number3 dw 0xDC3C
11011100
--addr 105--
00111100
each one is a bit and each address a byte, you can get the number of the address only moving the name that represent the address.
mov register/, numberN (this is the name of the addres)
And you can modify the content of a memory saying how many bytes you whant to take from the contents of memory starting in an address,
mov eax, number2
add dword, eax will modify the content of number2 and number3, because the size specified feet in this space.
Hope this help you more or get the idea ;), keep going.
Have a nice day or night.
Anyway I will mess you with my personals points of views, hope I dont miss you.
We do operations over memory, the memory can remember. Operations cant remember the previous state or the anterior source, but they "remember" how to do the operation (the process), because a "+" always can add two numbers, and in fact, the remembering is done inside the paths of execution of the processor, the processor can remember or follow the necesary paths for do the operation.
The ram memory have addresses, and inside or the content of each address is one byte, and this value can be readed or writed using [ and ] , depending if is source or destiny.
The registers (taked like memory), dosent have a address then you cannot obtain the addresses, but you can obtain/write the content of the address with his respective name: eax, ebx, esp, mmx1, mmx2, ... . Without the necesity of have the address of eax register and use [ and ] for read or write the content of the memory, only use the name and you can read/write the content.
The registers in the point of view of the operations only "see" a "number" inside each one.
But a important thing to note is that addresses of the ram memory can also have a representative name, because this address are only numbers or offsets, we use names for name a number address, like we do in math: 1 is one or *, 2 is two or **, ... ; but we give descriptive names normally: str1, str2, hWnd, ps, wc, etc.
When you move a name of RAM memory to another register or other memory, you actually are moving the address (number) to the destination. examples:
.data
str1 db "hola mundo como estas", 0
str2 db "hi worl I am OK", 0
address1 dd 0
address2 dd 0
.code
mov eax, str1
mov ebx, str2
mov [address1], str1
mov [address2], str2
This instructions have the same impact, you are modificating the content of memory first in the registers and then in the RAM.
When you move a address inside a register, you can add, substracts, andit, and all the operations, because the point of view of operations, but this operations are doing it to the number representing the address moved in, and for refer to the content of a number, you use [ and ] (with masm you should add two more words).
If you only whant to move 10 bytes above the a address dosent matter what contain or represent this address:
mov eax, nameOfAddress
add eax, 10
For example, you whant modify 5 continuos content of memory, add 1 dosent matter what mean that contents.
mov eax, nameOfAddress
mov ecx, 4 ;Why 4 and not 5?
add eax, ecx
again:
add byte[eax+ecx], 1
dec ecx
jnz again
You only whant to test if a memory is a number?, regarding if the number is 'a', 9, 'hi', etc?, only need be the same size against the size (number of bytes) that you are comparing against.
number represent 'a', '9', 4, a mask of bits, or any other inmediate number
size represent byte, word, dword, the number of bytes to take for comparation, if the other operand is a register, the size of the register is tacked automatically, and is for that, in the optional place is marked with orange.
mov eax, addressName
jmp firstTest
.again:
.add eax, size
.firstTest:
..cmp size, number
..jne again
I only write the dots for keep a little the format.....
If you only whant to get/write a content of memory you use []
mov eax,
mov eax, ebx
this two move the content in memory to eax register, but remember that with registers, you dont have to use [] and because you dont know the address.
By the end note:
--addr 101-- number1 db 0x4C
01001100
--addr 102-- number2 dw 0x0770
00000111
--addr 103--
01110000
--addr 104-- number3 dw 0xDC3C
11011100
--addr 105--
00111100
each one is a bit and each address a byte, you can get the number of the address only moving the name that represent the address.
mov register/, numberN (this is the name of the addres)
And you can modify the content of a memory saying how many bytes you whant to take from the contents of memory starting in an address,
mov eax, number2
add dword, eax will modify the content of number2 and number3, because the size specified feet in this space.
Hope this help you more or get the idea ;), keep going.
Have a nice day or night.
here is exactly what im trying to do. i kinda get it but there are a few things im messing up. but here is what i have. you may need to post this in an editor or something it appears this window isn't large enough to show it all.
Compare_Strings proc Strin:DWORD,Strin2:DWORD
mov eax,Strin ;move Strin in Eax
mov ebx,Strin2 ;mov Strin2 into Ebx
xor ecx,ecx ;ecx = 0
Continue: ;jump to here so we can loop through the bytes
inc eax ;increment eax
inc ebx ;increment ebx
inc ecx ;increment ecx (ecx = ecx + 1)
cmp byte ptr [eax+ecx],0 ;check if end of string in eax
je Done ;if end of string in eax stop comparing nothing left to do
cmp byte ptr [ebx+ecx],0 ;check if end of string in ebx
je Done ;if end of string in ebx stop comparing nothing left to do
cmp byte ptr [eax],byte ptr [ebx];compare first byte in eax to ebx
je Continue ;if they are equal we just keep going we don't need to know the equal bytes
movzx eax,al ;mov al into eax
push dword ptr eax ;add eax to our first listbox
push LB_ADDSTRING ;constant used to add the string to our listbox
push 1002 ;our first listbox
push 1000 ;our main dialog window
call SendDlgItemMessage ;call SendDlgItemMessage Because We Can't Use SendMessage ;x
movzx ebx,bl ;mov bl into ebx
push dword ptr ebx ;add eax to our first listbox
push LB_ADDSTRING ;constant used to add the string to our listbox
push 1003 ;our second listbox
push 1000 ;our main dialog window
call SendDlgItemMessage ;call SendDlgItemMessage Because We Can't Use SendMessage ;x
jmp Continue ;we aren't done comparing the string yet so jump to Continue:
Done: ;if we are done comparing the string we will jump to here
ret ;return and exit our function (not sure if a return is needed
Compare_Strings endp ;if it's eax isn't used when we are done)
you dont need in your case increment the content in eax and ebx, because you are incrementing ecx, then when you do:
inc eax
inc ebx
inc ecx
cmp byte ptr ,0
You are actually comparing one byte more far that the one you need to first compare.
You have two options, dont increment eax and ebx, and use them only like the base address, where the displacement is gived by ecx, and use a extra register, for the comparation of memory.
the second is that you can only incremen eax and ebx, and not use ecx like a offset, instead use it like a temporal container, for compare both memory locations.
cmp byte ptr ,byte ptr
Will not work, there is no direct comparation between memory content, instead use:
mov tempReg8bits,
cmp , tempReg8bits
Also what about if you first compare the content in the two strings, then check for the end of one of the strings?, if the first comparation is equal, and one of them have a zero, then boths should have a zero ;).
inc eax
inc ebx
inc ecx
cmp byte ptr ,0
You are actually comparing one byte more far that the one you need to first compare.
You have two options, dont increment eax and ebx, and use them only like the base address, where the displacement is gived by ecx, and use a extra register, for the comparation of memory.
the second is that you can only incremen eax and ebx, and not use ecx like a offset, instead use it like a temporal container, for compare both memory locations.
cmp byte ptr ,byte ptr
Will not work, there is no direct comparation between memory content, instead use:
mov tempReg8bits,
cmp , tempReg8bits
Also what about if you first compare the content in the two strings, then check for the end of one of the strings?, if the first comparation is equal, and one of them have a zero, then boths should have a zero ;).
Also what about if you first compare the content in the two strings, then check for the end of one of the strings?, if the first comparation is equal, and one of them have a zero, then boths should have a zero .
because what if they didn't give me a string at all?
Compare_Strings proc Strin:DWORD,Strin2:DWORD
mov eax,Strin ;move Strin in Eax
mov ebx,Strin2 ;mov Strin2 into Ebx
Continue: ;jump to here so we can loop through the bytes
inc eax ;increment eax
inc ebx ;increment ebx
cmp byte ptr ,0 ;check if end of string in eax
je Done ;if end of string in eax stop comparing nothing left to do
cmp byte ptr ,0 ;check if end of string in ebx
je Done ;if end of string in ebx stop comparing nothing left to do
mov cl,byte ptr
cmp byte ptr ,cl ;compare first byte in eax to ebx
je Continue ;if they are equal we just keep going we don't need to know the equal bytes
movzx eax,al ;mov al into eax
push dword ptr eax ;add eax to our first listbox
push LB_ADDSTRING ;constant used to add the string to our listbox
push 1002 ;our first listbox
push 1000 ;our main dialog window
call SendDlgItemMessage ;call SendDlgItemMessage Because We Can't Use SendMessage ;x
movzx ebx,bl ;mov bl into ebx
push dword ptr ebx ;add ebx to our first listbox
push LB_ADDSTRING ;constant used to add the string to our listbox
push 1003 ;our second listbox
push 1000 ;our main dialog window
call SendDlgItemMessage ;call SendDlgItemMessage Because We Can't Use SendMessage ;x
jmp Continue ;we aren't done comparing the string yet so jump to Continue:
Done: ;if we are done comparing the string we will jump to here
ret ;return and exit our function (not sure if a return is needed
Compare_Strings endp ;if it's eax isn't used when we are done)
now it doesnt crash or anything and i get my messagebox that says that there was no errors but for some strange reason its not adding anything to my listboxes.
mov eax,Strin ;move Strin in Eax
mov ebx,Strin2 ;mov Strin2 into Ebx
Continue: ;jump to here so we can loop through the bytes
inc eax ;increment eax
inc ebx ;increment ebx
cmp byte ptr ,0 ;check if end of string in eax
je Done ;if end of string in eax stop comparing nothing left to do
cmp byte ptr ,0 ;check if end of string in ebx
je Done ;if end of string in ebx stop comparing nothing left to do
mov cl,byte ptr
cmp byte ptr ,cl ;compare first byte in eax to ebx
je Continue ;if they are equal we just keep going we don't need to know the equal bytes
movzx eax,al ;mov al into eax
push dword ptr eax ;add eax to our first listbox
push LB_ADDSTRING ;constant used to add the string to our listbox
push 1002 ;our first listbox
push 1000 ;our main dialog window
call SendDlgItemMessage ;call SendDlgItemMessage Because We Can't Use SendMessage ;x
movzx ebx,bl ;mov bl into ebx
push dword ptr ebx ;add ebx to our first listbox
push LB_ADDSTRING ;constant used to add the string to our listbox
push 1003 ;our second listbox
push 1000 ;our main dialog window
call SendDlgItemMessage ;call SendDlgItemMessage Because We Can't Use SendMessage ;x
jmp Continue ;we aren't done comparing the string yet so jump to Continue:
Done: ;if we are done comparing the string we will jump to here
ret ;return and exit our function (not sure if a return is needed
Compare_Strings endp ;if it's eax isn't used when we are done)
now it doesnt crash or anything and i get my messagebox that says that there was no errors but for some strange reason its not adding anything to my listboxes.
What are you trying to achieve with
In your code, the apis will definitely modify the value in eax....
movzx eax,al ;mov al into eax
push dword ptr eax ;add eax to our first listbox
push LB_ADDSTRING ;constant used to add the string to our listbox
push 1002 ;our first listbox
push 1000 ;our main dialog window
call SendDlgItemMessage ;call SendDlgItemMessage Because We Can't Use SendMessage ;x
movzx ebx,bl ;mov bl into ebx
push dword ptr ebx ;add ebx to our first listbox
push LB_ADDSTRING ;constant used to add the string to our listbox
push 1003 ;our second listbox
push 1000 ;our main dialog window
call SendDlgItemMessage ;call SendDlgItemMessage Because We Can't Use SendMessage ;x
In your code, the apis will definitely modify the value in eax....
im comparing 2 files and im trying to add all the different bytes in the 2 files to 2 different listboxes. i have posted what the app looks like below
Then, this is wrong
You should be doing something like
Also please use esi or edi instead of eax in the loop. The api will definitely modify the value in eax.
movzx eax,al ;mov al into eax
push dword ptr eax ;add eax to our first listbox
push LB_ADDSTRING ;constant used to add the string to our listbox
push 1002 ;our first listbox
push 1000 ;our main dialog window
call SendDlgItemMessage ;call SendDlgItemMessage Because We Can't Use SendMessage ;x
You should be doing something like
movzx ecx, byte ptr[eax]
invoke dwtoh,ecx, offset buffer
invoke SendDlgItemMessage, 1000,1002, LB_ADDSTRING, offset buffer
Also please use esi or edi instead of eax in the loop. The api will definitely modify the value in eax.
because what if they didn't give me a string at all?
You are still quiting when you have a zero in one of both strings, doing first the comparation of the content of the string, can help in have 1 less comparation. And will still mark the diferent bytes.
ok well i got it to kinda work but instead of giving me the correct bytes it appears its giving me the current location of the bytes so i commented what doesn't work out and now i think i give up on this. so here is the source code what works isn't commented out and what is commented out
doesn't work.
~HeXeN
doesn't work.
~HeXeN