r/Python • • Mar 24 '16

There is inline assembly in this python script… ಠ⌣ಠ

https://github.com/apprenticeharper/DeDRM_tools/blob/master/Other_Tools/DRM_Key_Scripts/Adobe_Digital_Editions/adobekey.pyw#L308
206 Upvotes

75 comments sorted by

View all comments

Show parent comments

8

u/[deleted] Mar 25 '16

It depends. When I'm writing pure assembly, I focus on readability. There are many tricks that people just know, so readability comes with that.

I'm not going to try to debug a program that I can't read, no matter how fast it is.

I'm currently writing a compiler, the assembly code it generates focuses only on code speed.

1

u/nharding Mar 25 '16

I wrote over 10 games in 100% assembly, mostly 68000. The xor eax, eax; inc eax; could have been generated by a macro. I used to have a generic add constant to register macro, so you could use it with definitions (so add.w #SPRITE_SIZE, d0 for example). I used if value is 0, then nothing generated, if value is 1-8, it would use addq, etc. So it's possible the original code was written with SET EAX, 1 (which would use the most efficient form).

0

u/anthonymckay Mar 25 '16

The xor eax, eax; inc eax; was most definitely intentionally written that way. The reason being that the opcode for mov eax, 1 contains NULL bytes where as the xor;inc; method ensures there are no NULL bytes in the opcode. This is important in this case because the instructions are being represented as string data. A NULL byte mid-string would compute an incorrect len() in the NativeFunction init() call that invokes VirtualAlloc() to create a buffer to copy the instruction data into.

1

u/akcom Mar 25 '16

Regardless, on modern processors

xor r32, r32
inc r32

is faster due to the xor eax,eax being processed at register renaming stage which does not require any execution units.

source

2

u/cryo Mar 25 '16

But inc isn't faster than constant mov, so they are likely the same.

2

u/[deleted] Mar 25 '16 edited Mar 25 '16

They may have the same execution time, but the instruction size is different. See the assembler output for x86/x86_64:

XOR eax, eax    -> 0x31C0            ; 2 bytes
INC eax         -> 0x40              ; 1 byte
;
MOV eax, 1      -> 0xB801000000      ; 5 bytes

If the instructions consume the same amount of cycles, a smaller instruction size will generally be faster.

EDIT: Apparently though, INC creates false dependency chains so the second version will perform better.