The MASM Forum Archive 2004 to 2012

General Forums => The Campus => Topic started by: mineiro on August 19, 2010, 05:18:18 AM

Title: Memory operand problems
Post by: mineiro on August 19, 2010, 05:18:18 AM
I can compile this, but I get wrong results.

xor ecx,[edx+30303030h]

Can anybody more experience explain please.
regards.
Title: Re: Memory operand problems
Post by: dedndave on August 19, 2010, 05:50:32 AM
lol - that's an odd bump to an old thread
but, i am sure you are getting the correct results, for the code as shown
thing is - we can't tell you much without seeing the rest of the routine
it appears as though they are trying to convert 4 decimal bytes to ASCII with one instruction
although it is a little messed up - lol

you might see...
lea ecx,[edx+30303030h]
but, with XOR, they are going to get some strange results because edx+30303030h is likely to address some unpredictable data
Title: Re: Memory operand problems
Post by: mineiro on August 19, 2010, 06:04:33 AM
snippet source is:

atol_m proc lpSrc:DWORD
xor ecx,ecx
xor eax,eax
xor ecx,[edx+30303030h]
xor ecx,ecx
xor eax,eax
ret
atol_m endp

In olly I get this:


Address   Hex dump          Command                                  Comments
00401298   $  33C9          XOR ECX,ECX
0040129A   .  33C0          XOR EAX,EAX
0040129C      33            DB 33                                    ; CHAR '3'
0040129D  /.  8A30          MOV DH,BYTE PTR DS:[EAX]
0040129F  |.  3030          XOR BYTE PTR DS:[EAX],DH
004012A1  |.  3033          XOR BYTE PTR DS:[EBX],DH
004012A3  |.  C9            LEAVE
004012A4  |.  33C0          XOR EAX,EAX
004012A6  \.  C3            RETN

regards
Title: Re: Memory operand problems
Post by: dedndave on August 19, 2010, 06:10:26 AM
hmmmmm
it looks like olly is not aligned with the code - lol
it is not interpreting the 338A30303030 as a valid opcode, which i think it is
it is as though it is trying to disassemble it as 16-bit code - but i think the opcode would be valid there, too
something is very strange - there are no segment overrides

but, there is something wrong with the proc, too
i don't see where the lpSrc pointer value is loaded into a register
and - xor ecx,[edx+30303030h] is still going to get you garbage
at any rate, whatever is in ECX gets zeroed in the next line
where did you get this snippet ? - lol
Title: Re: Memory operand problems
Post by: mineiro on August 19, 2010, 06:23:48 AM
thank you for the answer Sr dedndave, this is only a test while I'm trying to write this procedure.
the code is align 16, so maybe this is the answer, I will try this one and later post here.
My idea is deal with this number on the fly (like a mask), without aloc it in .data session. You're right, the lpSrc is done nothing in this example. But if I do
xor ecx,[edx+3h] I get right results.
Thank you Sr.
regards.
Title: Re: Memory operand problems
Post by: mineiro on August 19, 2010, 06:55:54 AM
I changed the code(created with an wizard win32 in radasm)  and I'm getting access violation, so I presume it works, but in olly this give strange disasm.

xor eax,eax
here:
mov edx,offset here
xor ecx,[edx+3]
...

So, sorry for posting in wrong topic.
regards.
Title: Re: Memory operand problems
Post by: MichaelW on August 19, 2010, 07:54:27 AM

xor eax,eax
here:
mov edx,offset here
xor ecx,[edx+3]


The code runs OK for me.
Title: Re: Memory operand problems
Post by: mineiro on August 19, 2010, 08:21:55 AM
This code works here too Sr MichaelW, I have an illusion because ollydgb don't disasm this well.
Can anybody check the disasm of "xor ecx,[edx+30303030h]"
regards and thank you.

edited after
can anybody post the disasm of this proc:
disasm_test proc
xor ecx,ecx      
xor eax,eax
here:
xor edx,offset here
xor ecx,[edx+3333c090h]
xor ecx,[edx+909090h]
xor ecx,ecx
xor eax,eax
disasm_test endp
Title: Re: Memory operand problems
Post by: brethren on August 19, 2010, 01:38:45 PM
try deleting the udd file then run it through olly again
Title: Re: Memory operand problems
Post by: dedndave on August 19, 2010, 01:42:09 PM
this is generated by the assembler using the /Fl switch
00000013 disasm_test proc
00000013  33 C9 xor ecx,ecx     
00000015  33 C0 xor eax,eax
00000017 here:
00000017  81 F2 00000017 R xor edx,offset here
0000001D  33 8A 3333C090 xor ecx,[edx+3333c090h]
00000023  33 8A 00909090 xor ecx,[edx+909090h]
00000029  33 C9 xor ecx,ecx
0000002B  33 C0 xor eax,eax
0000002D disasm_test endp

here it is using a simple disassembler
:00401013 33C9                    xor ecx, ecx
:00401015 33C0                    xor eax, eax
:00401017 81F217104000            xor edx, 00401017
:0040101D 338A90C03333            xor ecx, dword[edx+3333C090]
:00401023 338A90909000            xor ecx, dword[edx+00909090]
:00401029 33C9                    xor ecx, ecx
:0040102B 33C0                    xor eax, eax
Title: Re: Memory operand problems
Post by: donkey on August 19, 2010, 02:16:14 PM
Here is a disassembly of the code you posted (without the stack frame stuff)

0040195A >/$ 31C9           XOR ECX,ECX
0040195C  |. 31C0           XOR EAX,EAX
0040195E  |. 81F2 5E194000  XOR EDX,40195E
00401964  |. 338A 90C03333  XOR ECX,DWORD PTR DS:[EDX+3333C090]
0040196A  |. 338A 90909000  XOR ECX,DWORD PTR DS:[EDX+909090]
00401970  |. 31C9           XOR ECX,ECX
00401972  |. 31C0           XOR EAX,EAX


Though the code makes little sense and will only lead to an access violation since the addresses you are using are not dereferenced.

Edgar
Title: Re: Memory operand problems
Post by: mineiro on August 19, 2010, 04:39:55 PM
Thank you for the answers.
In the first moment, I thinked that can be the odd/even address location of opcode in memory, but now I see that this is not true.
In second moment, i thinked that can be compiler ineficience (this is why I posted this one in that part of topic).
In the answer of sr donkey the first line produce opcode "31c9 31c0"h and in dedndave "33c9 33c0"h. In mine "33c9"h too, so I select this piece of code in ollydbg and click in "remove analysis from selection" to give right disasm, after deleting the .udd file.
Why the same code produce diferent opcodes is what I'm trying to understand now.
regards.
Title: Re: Memory operand problems
Post by: redskull on August 19, 2010, 04:45:38 PM
I seem to remember a thread about how MASM had a bug when compiling XOR, but since both operands are the same, it made no difference.

-r
Title: Re: Memory operand problems
Post by: mineiro on August 19, 2010, 04:56:51 PM
Yes sr redsdull, this makes no diference at all, because is like "mov ???,00". In my tests I do some referencing to a register, but now I erased it after so much tests. I simply cannot reproduce it again, but if I remember well, is something like:
xor ecx,ecx      
xor al,[edx+ecx+3]
xor cl,[ecx+ebx]
I'm using XOR here, because with xor you can [mov+cmp] in the same time, or "sub,add,zero,"... doing this while processors don't create a NAND opcode and mnemonic.
regards.
Title: Re: Memory operand problems
Post by: dedndave on August 19, 2010, 05:05:01 PM
 :bg
interesting to see the term "NAND" in here - lol
you must be in electronics
there is also no "NOR", or "XNOR"   :P
they would be handy sometimes

there are several instructions that have multiple valid coding
the assembler usually picks the shorter one, if any, because the performance is otherwise the same for most of these
Title: Re: Memory operand problems
Post by: mineiro on August 19, 2010, 05:23:01 PM
Sr dedndave, i come from electronics, hehehe, nor xnor(beer) .
With nand you can create others boolean "or,xor,and,not" and "nor, xnor,...". If we have this very optimized opcode and not (NOT AND)(1+1 cycles), I thinked in this while trying to optimize some code, but this give me an error that I simply cannot reproduce again.
Thank you for the answer, session good times.
Title: Re: Memory operand problems
Post by: mineiro on August 19, 2010, 07:10:13 PM
I doing some research in this, the first code that I posted don't do nothing, but this one do what I'm thinking.

IF 0  ; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
                      Build this template with "CONSOLE ASSEMBLE AND LINK"
ENDIF ; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
    include \masm32\include\masm32rt.inc
    .code
start:
xor eax,eax
xor edx,edx
xor edx,offset start
xor al,[eax+edx]
xor al,33h
je @F
xor al,33h
print str$(eax),09h
print "cannot say about your compiler",13,10
inkey
exit
@@:
xor al,33h
print str$(eax),09h
print " you compiled with Masm32?(R), opcode 33h", 13, 10
    inkey
    exit
end start

regards.
Title: Re: Memory operand problems
Post by: clive on August 19, 2010, 08:01:58 PM
The 0x31 vs 0x33 is a source vs destination issue, and the mod/rm encoding

000000BB  31 05 00000000 R         xor     dword ptr [start],eax
000000C1  33 05 00000000 R         xor     eax,dword ptr [start]


and the 11yyyxxx encoding for reg,reg. The 31 variant is xor regx,regy, the 33 is xor regy,regx

000000BB 310500000000           xor     [_start],eax
000000C1 330500000000           xor     eax,[_start]
000000C7 31C0                   xor     eax,eax
000000C9 31C9                   xor     ecx,ecx
000000CB 33C0                   xor     eax,eax
000000CD 33C9                   xor     ecx,ecx
000000CF 31CA                   xor     edx,ecx
000000D1 33CA                   xor     ecx,edx


Like may architectures, the x86 is rife with multiple ways to encode the equivalent function.
Title: Re: Memory operand problems
Post by: mineiro on August 19, 2010, 08:10:30 PM
now I get the point Sr clive. So how can we make assumptions (like is said in intel manual)? Well, speaking in not my native language is dificult to me.
How can we predict(or do some predictions to the processors) to get faster code?
thank you Sr.
added after because I get an english dictionary.
I now confused by some factors(the xor ambiguity) , if the left operand(in 8086 architeture) every time receives the right operand, why this happens?
xor left, right
xor destin, source.
thanks in advance Sr's.
Title: Re: Memory operand problems
Post by: clive on August 19, 2010, 08:38:00 PM
When it cost cycles to read opcode bytes the short ones ran faster, these days it is mostly irrelevant. Increasing code density will improve cache utilization, but branches like to be on cache-line boundaries. The assembler/compilers usually pick the shortest form, the long form may be used when the assembler doesn't know the value (imported from another object), and the linker gets to fix it up, but can't revert to the short form.

Long and short forms of ADD EAX,1

000000D3 83C001                 add     eax,1
000000D6 0501000000             add     eax,1


Long and short forms of ADD EAX,-1

000000DB 83C0FF                 add     eax,0FFFFFFFFh
000000DE 05FFFFFFFF             add     eax,0FFFFFFFFh
Title: Re: Memory operand problems
Post by: clive on August 19, 2010, 08:52:09 PM
Quote from: mineiro
I now confused by some factors(the xor ambiguity) , if the left operand(in 8086 architeture) every time receives the right operand, why this happens?
xor left, right
xor destin, source.

The 8086 "the machine" has one general way to encode a memory address (or register) and a register, depending on the opcode this can refer to REG to MEM/REG, or REG from MEM/REG. The assembler syntax always has a "right goes to left" to present a common view/syntax to the human, the assembler picks the machine code to use to encode the instruction.

Observe that the machine instructions are practically identical as they define the register and the memory. The first has the memory as the destination, the second has the memory as the source.

000000BB 310500000000           xor     [_start],eax
000000C1 330500000000           xor     eax,[_start]


The 68000 assembler has the reverse view, but again the machine code has a mostly common encoding for the effective address, and separate TO/FROM versions of the opcode encoding.

There are the reverse of each other

000000CF 31CA                   xor     edx,ecx ; EDX = EDX eor ECX
000000D1 33CA                   xor     ecx,edx ; ECX = ECX eor EDX


These are simply equivalent

000000C7 31C0                   xor     eax,eax ; EAX = EAX eor EAX
000000C9 31C9                   xor     ecx,ecx ; ECX = ECX eor ECX
000000CB 33C0                   xor     eax,eax ; EAX = EAX eor EAX
000000CD 33C9                   xor     ecx,ecx ; ECX = ECX eor ECX


Interestingly the 68000 has the equivalent to MOVE MEM/REG to MEM/REG, so you can get a memory-to-memory operation that does not use a register.
Title: Re: Memory operand problems
Post by: mineiro on August 19, 2010, 09:13:31 PM
Now I understand, thank you.
When I have seen the "convert signed dword ascii to hex" I think in this way:
Build a two complement of one byte(to later combine/organize), transform it to boolean algebra, optimize it with Karnaugh. Ok, this is the bit circuit, now I translate it to pc.
When I come to pc I cannot get the fastest code thinking in this way.
So, thanks to everybody that have posted, appreciate much yours words.
regards.
Title: Re: Memory operand problems
Post by: clive on August 19, 2010, 09:33:31 PM
I think you are confusing clever tricks with LEA doing addition, with doing address accesses with XOR. The thing here is that LEA doesn't do an address access, just computes the "address" that would have been accessed and thus won't generate faults.

Multiply EAX by 10, add in EBX ASCII digit


  ADD EAX,EAX ; *2
  LEA EAX,[EAX+EAX*4] ; *5

  LEA EAX,[EAX+EBX-30h] ; EBX = ASCII '0' - '9'

Title: Re: Memory operand problems
Post by: mineiro on August 19, 2010, 09:51:10 PM
Yes, I figure that.

xor eax,30h   ;sub 30h
shl eax,1 ;mul by 2
xor ecx,eax  ; add it to zeroed ecx
shl eax,2 ; mul by 8 (it is mul by 2)
add ecx,eax

Or others ways, like "mul by 5 == div by 2" in decimal,  and after rearrange.
Title: Re: Memory operand problems
Post by: mineiro on August 19, 2010, 11:17:58 PM
I don't write the word "Sr" but I have this in mind ok.
I re-read(and learned much with the words here) what you posted clive, so in your example:

000000D3 83C001                 add     eax,1
000000D6 0501000000             add     eax,1

Using this we get more speed than using a simple "inc eax"?

004018D0  40            INC EAX

And another question, how did you compile to get that long way? In my tests I can do it with "db 05h,01h,00h,00h,00h", is this the way?
Oh, yes, and why about(what means) "align 16"?
I understand align 16 like a fit your opcode in a way that it produces 16 bytes in the end. So, if this is true, maybe we can have a generic pseudo algo code that is every time aligned and with this get better speeds?
regards.
Title: Re: Memory operand problems
Post by: clive on August 20, 2010, 01:29:24 AM
ADD beats INC for most CPU's in recent memory. However INC does not change carry flag, so it has it's uses. LEA doesn't change any flags.

Microsoft (R) Macro Assembler Version 6.15.8803     08/19/10 20:22:07
test40.asm      Page 1 - 1


        .386
        .MODEL FLAT
00000000         .CODE

00000000 _start:

00000000  83 C0 01         add     eax,1
00000003  83 C0 04         add     eax,4
00000006  05 00000001         add     eax,dword ptr 1
0000000B  05 00000004         add     eax,dword ptr 4

        END     _start
Title: Re: Memory operand problems
Post by: mineiro on August 20, 2010, 02:06:32 AM
thank you, now I read some optimization docs (Agner an Mark). My fault is not doing the little logic, but, translate that into pc world.
I learn a lot with this topic, much brainfood to one day. Like Kasparov says, have minimalistics and maximalistics guys. I reached the Karpov, now I want a challenge with Kasparov.
Case closed.
regards.
Title: Re: Memory operand problems
Post by: dedndave on August 20, 2010, 02:07:38 AM
we all have to start someplace
you are doing great   :U
i used to play a little chess   :P
Title: Re: Memory operand problems
Post by: mineiro on August 20, 2010, 03:09:55 AM
and of course, thank you (with much respect) minimalistic dedndave.
http://chessprogramming.wikispaces.com/General+Setwise+Operations
case closed  -<(not more ambiguity xor)
Title: Re: Memory operand problems
Post by: dedndave on August 20, 2010, 03:21:05 AM
http://computer-chess.org/doku.php?id=home
Title: Re: Memory operand problems
Post by: mineiro on August 20, 2010, 04:23:03 AM
dedndave, fantastic link 
I now thinking in how much time I need to put the opcodes to fight and give the check mate in less moves; while this I'm doing an opening(ECO) book.
:clap: regards.