Add two 32-bit integers to Assembler for use in VB6

I would like to come up with assembler byte code (assembly?) For Windows machines to add two 32-bit longs and throw away the carry bit. I understand that part of the โ€œWindows machineโ€ is a bit vague, but I assume that the bytes for ADD almost the same in all modern Intel instruction sets.

I'm just trying to work a bit with VB and do some things faster. So ... if the line "8A4C240833C0F6C1E075068B442404D3E0C20800" is the assembly code for SHL that can be "injected" into the VB6 program for fast SHL waiting for two long parameters (we ignore here that the 32-bit longs in VB6 are signed, just pretend that they are unsigned), which is the sixth line of bytes representing assembler instructions that will do the same to return the sum?

The hex code above for SHL , according to the author:

 mov eax, [esp+4] mov cl, [esp+8] shl eax, cl ret 8 

I insert these bytes into a file and try to parse them on the Windows command line using the old debugging utility, but I realized that it does not work with the new command set because I did not like EAX when I tried to collect something, but it was pleased with the AX .

I know from the comments in the source code that SHL EAX, CL is D3E0 , but I have no link to know what bytes are for the ADD EAX, CL command, or I will try. (Although now I know that the operands must be the same size.)

I tried flat assembler and don't get anything that I can figure out how to use. I used it to build the SHL source code and got a completely different result, not the same bytes. Help?

+4
source share
1 answer

I parsed the bytes you provided and got the following code:

 (__TEXT,__text) section f: 00000000 movb 0x08(%esp),%cl 00000004 xorl %eax,%eax 00000006 testb $0xe0,%cl 00000009 jne 0x00000011 0000000b movl 0x04(%esp),%eax 0000000f shll %cl,%eax 00000011 retl $0x0008 

Which is definitely more complicated than the source code provided by the author. It checks that the second operand is not too large, for example, which is not in the code that you showed at all (see Section "Editing 2" below for a more complete analysis). Here's a simple stdcall function that combines two arguments and returns the result:

 mov 4(%esp), %eax add 8(%esp), %eax ret $8 

An assembly that gives me this conclusion:

 (__TEXT,__text) section 00000000 8b 44 24 04 03 44 24 08 c2 08 00 

I hope these bytes do what you want!

Edit: perhaps more useful, I just did the same in C:

 __attribute__((__stdcall__)) int f(int a, int b) { return a + b; } 

Compiled with -Oz and -fomit-frame-pointer , it generates exactly the same code (well, functionally equivalent, anyway):

 $ gcc -arch i386 -fomit-frame-pointer -Oz -c -o example.o example.c $ otool -tv example.o example.o: (__TEXT,__text) section _f: 00000000 movl 0x08(%esp),%eax 00000004 addl 0x04(%esp),%eax 00000008 retl $0x0008 

Machine Code Output:

 $ otool -t example.o example.o: (__TEXT,__text) section 00000000 8b 44 24 08 03 44 24 04 c2 08 00 

Will certainly hit the build code manually!

Edit 2:

@Emtucifor asked in the comments below what would happen if an attempt was made to shift 32 bits or more. The split code at the top of this answer (for bytes provided in the original question) can be represented by the following higher-level code:

 unsigned int shift_left(unsigned int a, unsigned char b) { if (b > 32) return 0; else return a << b; } 

From this logic, itโ€™s pretty easy to notice that if you pass a value greater than 32 as the second parameter of the shift function, you just get 0 back.

+4
source

Source: https://habr.com/ru/post/1339292/


All Articles