I can compile this, but I get wrong results.
xor ecx,[edx+30303030h]
Can anybody more experience explain please.
regards.
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
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
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
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.
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.
xor eax,eax
here:
mov edx,offset here
xor ecx,[edx+3]
The code runs OK for me.
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
try deleting the udd file then run it through olly again
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
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
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.
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
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.
: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
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.
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.
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.
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.
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
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.
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.
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'
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.
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.
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
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.
we all have to start someplace
you are doing great :U
i used to play a little chess :P
and of course, thank you (with much respect) minimalistic dedndave.
http://chessprogramming.wikispaces.com/General+Setwise+Operations
case closed -<(not more ambiguity xor)
http://computer-chess.org/doku.php?id=home
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.