News:

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

some stupid comparison problem...

Started by psychocode, August 17, 2007, 06:37:02 PM

Previous topic - Next topic

psychocode

sorry again for the copy/paste from irc, but didn't wanted to rewrite it again...

[21:28] <psycho32> there's a table like that: vx86_opcodes dd "spon", offset vx86_nop ; nops (nop equivalent) ; MISC opcodes TABLE here
[21:28] <psycho32>         dd "spmj", offset vx86_jmps ; jmps (jmp)
[21:28] <psycho32> etc...
[21:28] <psycho32> the comparison code, that is failing is this:
[21:29] <psycho32>     cmp dword ptr [eax], ebx ; else compare for opcode
[21:29] <psycho32>     jne @check_nxt_opcode ; if not that case, repeat
[21:29] <psycho32>     add ebx, 04h ; if opcode found, jump to corresponding opcode's routine
[21:29] <psycho32>     jmp ebx 
[21:31] <psycho32> however, the cmp due to some strange reason doesn't alter the zero flag, when comparing - for example dword ptr [eax] contains pons, when cmped to the 1st element of the table, the jne activates
[21:31] <psycho32> any idea about wtf is wrong with this?!
[21:32] <psycho32> ebx contains the current address in the table
[21:33] <psycho32> eax contains the buffer of the file to be parsed

that's the situation, but i'm unable to get it why it doesn't work as supposed... :dazzled:

BogdanOntanu

Could it be that this is copy and paste again?
Again too much text to write for a decent nice presented question?
Saving some time...yeah?

Well then...  I will also save some time and I will not answer your question ...

although it is indeed trivial in nature

Ambition is a lame excuse for the ones not brave enough to be lazy.
http://www.oby.ro

psychocode

yeah, right, that's the question:
there's a table like this:
vx86_opcodes dd "spon", offset vx86_nop ; nops (nop equivalent) ; MISC opcodes TABLE here
         dd "spmj", offset vx86_jmps ; jmps (jmp)
etc...

comparison code:
    cmp dword ptr [eax], ebx ; else compare for opcode
    jne @check_nxt_opcode ; if not that case, repeat
    add ebx, 04h ; if opcode found, jump to corresponding opcode's routine
    jmp ebx 

however, the cmp due to some strange reason doesn't alter the zero flag, when comparing - for example dword ptr [eax] contains pons, when cmped to the 1st element of the table, the jne activates
ebx contains the current address in the table and eax contains the buffer of the file to be parsed  :dazzled:


BogdanOntanu

Quote from: psychocode on August 17, 2007, 08:13:41 PM
yeah, right,

:naughty:

Quote
that's the question:
there's a table like this:
vx86_opcodes dd "spon", offset vx86_nop ; nops (nop equivalent) ; MISC opcodes TABLE here
         dd "spmj", offset vx86_jmps ; jmps (jmp)
etc...

1.what makes you think that OPCODES strings do fit in 4 bytes or a DWORD?
2.Why are the strings backwards?
Hint:Whit some extra DES+AES+etc you could make the table more complicated and still not functional
3.Padding with "s" is "pricelesssssssssss"

Conclusion: the data structures you choose are completely wrong for the task at hand or for your level of expertise.

Quote
comparison code:
    cmp dword ptr [eax], ebx ; else compare for opcode
    jne @check_nxt_opcode ; if not that case, repeat
    add ebx, 04h ; if opcode found, jump to corresponding opcode's routine
    jmp ebx 


Showing us bits of code that does not even contain relevant initializations is always expected and appreciated on this forum. We usually read minds and know the problem of the poster by heart.

However we refuse to answer until the poster formats his questions nicely but still leaves relevant code parts out of the picture.

We always appreciate NOT TO KNOW:
- where are registers like eax and ebx initialized
- where and how are pointers incremented
- how is the loop controlled

However... in this case:

1) Comparing data pointed by EAX with EBX is like comparing DATA with ADDRESS or apples with oranges
2) JMP EBX is like launching space shuttle into the ground. It might flap or it might explode...who knows. I bet you wanted to jump at the routine  pointed by EBX?

Quote
however, the cmp due to some strange reason doesn't alter the zero flag, when comparing

We all have our "strange" days and we all know that random events like the shine of the Moon on the waters of the lake DO INFLUENCE CMP instructions in assembly...

However, with this code this is not the case....

Hint: in programming any error in 99.999% the fault of the programmer.

Quote
- for example dword ptr [eax] contains pons, when cmped to the 1st element of the table, the jne activates
ebx contains the current address in the table and eax contains the buffer of the file to be parsed  :dazzled:

Considering that: "EBX contains the address in the table"...
WHY I am not surprised that jne "activates".
I guess the computer it trying to tell you a story.

Hints:
1) I also do not think that EAX is capable to "contain the buffer to be parsed"... EAX is too small for that. Maybe it contains the current address in the buffer to be parsed? But then we all know that beeing EXACT is of no relevance in programming... especially in ASM. ("Computer... Engage!")
2) ASCII strings are just a series of bytes.
3) Consider breaking source data into "tokens" and then comparing those with your tables.
4) Do not (i repeat: do not) reverse your strings

Please try to consider them like bytes instead of DWORDS for a while...see what happens...

Hint: the campus forum is more protected from such ironical remarks ;)

Ambition is a lame excuse for the ones not brave enough to be lazy.
http://www.oby.ro

psychocode

i never meant to offend someone by 'yeah, right', just english isn't my native language, sorry

about the opcodes, fitting in 4 bytes/dword - each letter is encoded in ascii by one byte as far as i know and nops = 4 letters/byte, correct me if i'm wrong...
strings are backwards becouse of the dword and little/big endian ordering...
padding with s was the first thing that came to my mind at the moment :)

what data structures would be better in your opinion for the task i'm trying to accomplish?

the initializations were missing, cuz the code is a lil' bit of a spaghetti code, but here they are:

init:
@init_vx86_parser:
    lea ebx, vx86_opcodes ; load the opcode table in ebx
    mov currentoptbl,ebx ; saving table's beginning

parsecode proc membuff:DWORD ; param1 - memory buffer addr, param2 - target architecture, on failure returns 0...
LOCAL linecount:DWORD ; line counter
LOCAL currentline:DWORD ; current line
LOCAL currentofs:DWORD ; current offset
LOCAL currentoptbl:DWORD ; current position in opcode table...

    mov ebx,membuff ; file buffer goes in ebx

    mov eax,membuff ; memory buffer goes in eax
    xor ecx,ecx ; initializing counter...


incrementations (that's actually a large part of the main parser loop...) :

@vx86_parse_opcode:
    cmp byte ptr [eax], ";" ; check if line begins with comment...
    jz @goto_next_line
    cmp byte ptr [eax], 0Ah
    jnz @F
    cmp byte ptr [eax], 0Dh
    jnz @F
    inc eax
    jmp @vx86_parse_opcode
@@: cmp dword ptr [eax], endmark
    je @code_parsed
    cmp dword ptr [eax], ebx ; check for opcode loop...
    jne @nxt
    add dword ptr [ebx], 04h
    jmp ebx

@nxt:    cmp dword ptr [ebx], endmark
    jz @reload_tbladdr ; if table is over, operand is not recognized, so reload table's address and continue
    add ebx, 08h
    jmp @vx86_parse_opcode

@reload_tbladdr: mov ebx, currentoptbl

2) JMP EBX is like launching space shuttle into the ground. It might flap or it might explode...who knows. I bet you wanted to jump at the routine  pointed by EBX? -> exactly that was the idea...

Hint: I also do not think that EAX is capable to "contain the buffer to be parsed"... EAX is too small for that. -> it contains the address of the buffer, not the buffer itself indeed, as i said before, english is not my native...

so what's the problem's solution?

BogdanOntanu

Quote from: psychocode
i never meant to offend someone by 'yeah, right', just english isn't my native language, sorry

about the opcodes, fitting in 4 bytes/dword - each letter is encoded in ascii by one byte as far as i know and nops = 4 letters/byte, correct me if i'm wrong...
strings are backwards becouse of the dword and little/big endian ordering...
padding with s was the first thing that came to my mind at the moment :)

what data structures would be better in your opinion for the task i'm trying to accomplish?

the initializations were missing, cuz the code is a lil' bit of a spaghetti code, but here they are:

init:
@init_vx86_parser:
    lea ebx, vx86_opcodes ; load the opcode table in ebx
    mov currentoptbl,ebx ; saving table's beginning

parsecode proc membuff:DWORD ; param1 - memory buffer addr, param2 - target architecture, on failure returns 0...
LOCAL linecount:DWORD ; line counter
LOCAL currentline:DWORD ; current line
LOCAL currentofs:DWORD ; current offset
LOCAL currentoptbl:DWORD ; current position in opcode table...

    mov ebx,membuff ; file buffer goes in ebx

    mov eax,membuff ; memory buffer goes in eax
    xor ecx,ecx ; initializing counter...


incrementations (that's actually a large part of the main parser loop...) :

@vx86_parse_opcode:
    cmp byte ptr [eax], ";" ; check if line begins with comment...
    jz @goto_next_line
    cmp byte ptr [eax], 0Ah
    jnz @F
    cmp byte ptr [eax], 0Dh
    jnz @F
    inc eax
    jmp @vx86_parse_opcode
@@: cmp dword ptr [eax], endmark
    je @code_parsed
    cmp dword ptr [eax], ebx ; check for opcode loop...
    jne @nxt
    add dword ptr [ebx], 04h
    jmp ebx

@nxt:    cmp dword ptr [ebx], endmark
    jz @reload_tbladdr ; if table is over, operand is not recognized, so reload table's address and continue
    add ebx, 08h
    jmp @vx86_parse_opcode

@reload_tbladdr: mov ebx, currentoptbl

2) JMP EBX is like launching space shuttle into the ground. It might flap or it might explode...who knows. I bet you wanted to jump at the routine  pointed by EBX? -> exactly that was the idea...

Hint: I also do not think that EAX is capable to "contain the buffer to be parsed"... EAX is too small for that. -> it contains the address of the buffer, not the buffer itself indeed, as i said before, english is not my native...

so what's the problem's solution?


You have to find the solution by yourself ;)

There are too many errors to mention. I guess some extra code is missing.

Do not worry I was not offended.

English is not my native ...  language either.  I also speak French, German, Italian, Spanish and of course native.
Let us try to use some decent English on this planet.

A few notes:
- opcode mnemonics are variable in length, some are over 4 bytes like: movsd, movsb, cpuid, rdtsc, finit,  MMX and SSE etc.
- You will not get too far with fixed 4 bytes per mnemonic.
- even if you make it work the way you compare is inefficient.
- Follow my advice and try to learn about tokens and write a tokenizer.
- do not to write spaghetti code
- factorize: break code into smaller more easy to implement procedures. Give each one a clear interface. Understand PROC.
- do not fall into procedure's prologue code
- do not  write hacked spaghetti code
- do not setup procedure local variable from outside the procedure body
- do not  write spaghetti code
- methods are supposed to be called not to be jumped into... usually
- do not  write spaghetti code
- understand the diference between [EBX] and EBX
- do not try to make up code by copy and paste and peeking advice; instead try to understand the basic concepts first.
- do not to write spaghetti code
- by the look of your code this task looks much too complicated for your current knowledge and understanding level.
- Try to find something more easy to do first.
- where is param2 ?
- do not  write spaghetti code
- until you become more advanced stay away from anonymous labels like @@ and @F @B.
- Give your labels meaningful clear names.
- do not  write spaghetti code
- why are eax and ebx init with same "membuff"
- do not  write spaghetti code
- stop trying to make this up. ( add dword ptr [ebx], 04h )

:green

Ambition is a lame excuse for the ones not brave enough to be lazy.
http://www.oby.ro

psychocode

- opcode mnemonics are variable in length, some are over 4 bytes like: movsd, movsb, cpuid, rdtsc, finit,  MMX and SSE etc.
- You will not get too far with fixed 4 bytes per mnemonic.
- even if you make it work the way you compare is inefficient. --> it's not that much of an issue at the moment... as far as mnemonics, this compiler is not actually for an existing cpu architecture... it's for an imaginery one ;) it's purpose is to be a part of a software protection scheme... some things are not exactly as they seem to be  :8) and i'm not planning to use mnemonics, longer than 4 bytes, in this arch... at least at the moment. about the efficiency - it's gonna be optimized when it's needed and moreover i don't think that the code that's gonna compiled by this 'compiler' is ever gonna be that big and complicated for the efficiency to be of any concern ;)

- methods are supposed to be called not to be jumped into... usually -> i guess i'm not coding high level stuff in this case
- do not try to make up code by copy and paste and peeking advice; instead try to understand the basic concepts first. -> there's no copy/paste in this code
- where is param2 ? -> the code for param2 handling is to be constructed and it's not used at the current stage of this 'project'... it's just as a reminder for TODO list :)
- do not  write hacked spaghetti code -> spaghetti code in this case is not much of an issue, since when i get it to work, i'm not going to alter this parsecode routine - the purpose of the second parameter is to specify a different, again imaginery, architecture... new arch = calling a corresponding parser (new arch = new parser coded)... and btw what do you mean by "hacked spaghetti code"?

- stop trying to make this up. ( add dword ptr [ebx], 04h ) -> i need to get things done and this is a fast and easy for implementation way...

after so many bytes said on the topic, i actually failed to see something ON the real question -> WHY these 2 lines of code for the comparison DON'T work? that was the question... if there were optimization issues, i would've asked: "hey, how to optimize this code?". But if that was the case, i wouldn't even have asked, i would use google for code optimization techniques tutorials and books... 10x for all the useful advices, but they did NOT help to get things DONE  ::)

i SOLVED the problem, this way works EXACTLY as SUPPOSED to:

@@: cmp dword ptr [eax], endmark
    je @code_parsed
    mov edx, dword ptr [ebx]
    cmp dword ptr [eax], edx
    jne @nxt
    add ebx, 04h
    jmp dword ptr [ebx]

was it that hard to save some of my hours and so much of your writing by telling me this in the begining?  :cheekygreen:

MichaelW

Quotewas it that hard to save some of my hours and so much of your writing by telling me this in the begining?

Was it that hard to thank Bogdan for taking his time to analyze your code and reply? I looked at your post and decided that trying to help you was not worth the effort, considering that it apparently wasn't worth your spending a few minutes to "rewrite it again", or to post all the relevant parts, or to clearly state what you were trying to do. Even if it's not intentional, making it difficult for people to help you is not a good way to get help.
eschew obfuscation

psychocode

it's just that he gave me some advices, that had nothing much to do with the specific problem, while the exact problem i asked for help with - i had to solve alone... but i asked for help with something specific, not for generic programming guidelines... however 10x

hutch--

psycho,

When you lay out a question in such a manner you are lucky that anyone would try and answer it. An IRC text paste is no joy to read and your posting gave almost no context for the code to run in. Next ime you have a complicated question think of the person who tries to answer it for you and give them as much context as is needed to understand it.

We have enough magicians here to start with but short of magic they cannot read your mind.
Download site for MASM32      New MASM Forum
https://masm32.com          https://masm32.com/board/index.php

psychocode

yep, hutch, you're right, but i corrected that - i layed the question correctly after that, yet i never got an answer on that question - that was my point...
regards, psychocode

BogdanOntanu

The answer to your initial question was given above in those statements:

Quote from: bogdan ontanu
1) Comparing data pointed by EAX with EBX is like comparing DATA with ADDRESS or apples with oranges
2) JMP EBX is like launching space shuttle into the ground. It might flap or it might explode...who knows. I bet you wanted to jump at the routine  pointed by EBX?

The first point is the answer to your problem (ie why the CMP is failing)
The seccond point shows you a problem that you will encounter in the future IF you solve the first point.

However you choose to ignore them.

In another statement that I have made above (not shown here) I have suggested that you should learn the difference in between EBX and [EBX].

The pointer is not the same with the data it points at.
A pointer is just an indicator pointing towards the data...
Do you see the "point" Oblio?

The rest is silence.
Ambition is a lame excuse for the ones not brave enough to be lazy.
http://www.oby.ro