I have the following instruction in my MASM program:

add ebx, byte ptr 55h

This instruction could be compiled to the following bytes (hex):


83 C3 35


But MASM compiles it to the following bytes:


81 C3 55 00 00 00


I.e., it uses the 32-bit immediate opcode, even though it would save place (and theoretically speed) to use the 32/8-bit immediate opcode in my example. Even though I'm explicitly using the "byte ptr" coercion operator to make it understand better what I want, it still doesn't do it. :(


My question is:

Is there any other types of coercion operators in MASM besides "ptr"?

As you can see, I'm looking for e.g. operators that can be used to decide which opcode to use when there are several possible opcodes for a certain instruction, or at least something that will make MASM e.g. optimize the instructions for size.

Any tips whatsoever would be greatly appreciated.

Thanks!


PS.
I know I can easily make a macro for it in the example above (which is exactly what I am doing right now), but it would be much nicer to be able to tell MASM what I want it to do, instead of building custom macros for a lot of instructions.

PS2.
Yes, I'm still working on my minimal exe packer, it's going slooow. :)
Posted on 2003-02-12 11:47:18 by dELTA
If I understand you right and you want to add an immediate value, then add ebx,55h does assemble to 83 c3 55

add ebx,byte ptr 55h means add the contents of the byte at memory 55h to ebx - hence 81 c3 55 00 00 00

By habit (I used TASM once...) I put memory references in square brackets (which MASM permits) this usually prevents me from confusing myself :)
Posted on 2003-02-12 17:13:14 by eGo
Thanks, but no, both those opcodes add an (absolute) immediate value to a register. The only difference is that the 81 opcode uses a 32-bit immediate value with a 32-bit register, and the 83 opcode uses an 8-bit immediate value with a 32-bit register. The only difference (when using an immediate value less than 256) is the size of the opcode operands in the compiled code.
Posted on 2003-02-12 17:20:55 by dELTA
dELTA,

The problem is the obvious one, if you add a pointer to BYTE data to DWORD data, you will end up with a DWORD result. The BYTE PTR operator is telling the assembler to address a BYTE at an address, it actually performs SIZE casting.

Tell us what you are trying to do and there may be a better way to do it.

Regards,

hutch@movsd.com
Posted on 2003-02-12 18:03:45 by hutch--
Yes, I suspected that the ptr operator was not right, it was just a last desperate attempt from my side. :( That's why I was wondering if there are any other similar coercion operators that would be more correct.


What I want to do it simply this:

Make MASM use the most space efficient opcode for the following operation:

add ebx, 55h

Since the immediate value is less than 256, it would be best to compile it to:

83 C3 35

But MASM insists on using the 32-bit immediate value version, which is 3 bytes bigger:

81 C3 55 00 00 00


So, can I tell MASM to use the smaller, more optimal, opcode in any way?
Posted on 2003-02-12 18:12:44 by dELTA
Hmm, that is odd.
My ml.exe from MASM32v7 package does what you want. What version of MASM do you use?
Posted on 2003-02-12 20:14:42 by Starless
Ok, the real value in my program was FFh, I only used 55h in my example here, I didn't think that it would do any difference. :(

I just tried, and if the immediate operand is 7F or less, the small version is used. So, MASM seems to treat the operand as signed, and determine the "border" based on this, but is there really any reason whatsoever not to use the small type opcode all the way up to FFh? Anyone?
Posted on 2003-02-13 06:07:36 by dELTA
The CPU does SIGNED extension so if you use the opcode:

83 C3 FF

the CPU would extend 0FFh (-1) to 0FFFFFFFFh (-1) which is not what you want.
Posted on 2003-02-13 06:18:19 by gliptic
Actually it is exactly what I want :), but ok, now I see why some people would like to use the bigger opcode for those numbers sometimes.

It would be cool to be able to use some kind of coercion operator in MASM to tell that the immediate constant really is supposed to be signed though, and this is very similar to what I was looking for to begin with.

So, is there any way to cast an immediate operand to signed/unsigned in MASM? Anyone?

Thanks!
Posted on 2003-02-13 10:03:44 by dELTA
FF is not -1. So if you want the short form for -1, you use -1. As the value to be used is 32-bits, the value of -1 will be FFFFFFFF, not 000000FF. The assembler simply sees that all of the necessary high order bits are 1's, so that it can use the short form.

Say what you mean!
Posted on 2003-02-13 13:38:32 by tenkey