Each instruction is encoded and is in RAM when executed (well, it's in the icache, but let's keep it simple).

Try compile this and look at the resulting binary file:

Code:

use32
mov eax, ebx

It should be the two bytes 89 D8 (in hex), this is the encoding of the instruction (each instruction is encoded differently and has varying length) and what the CPU executes.

Now try:

Code:

use32
mov ax, bx

It should be 66 89 D8, as you can see it's the same two bytes at end but with a 66 byte prefix in front of it so now it's 3 bytes long, which tells it to use 16-bit operands instead of 32-bit. (this is in 32-bit mode). This is simply how the CPU works, they could've designed it some other way, but it isn't...

There is no encoding for "mov eax, bx" that's why FASM won't compile it. (well not in the x86 architecture, which is what we're talking about)

Note that an actual binary executable won't start with the insns and have only the instructions. Though we didn't specify so FASM simply outputs binary for instructions. (useful for testing / learning ).

It doesn't answer why it doesn't compile, which is what he asked. Why. Your answer was "because the golden rule blah, with few exceptions".

So if he asks "why does shl eax, cx fail to assemble but shl eax, cl works?" what will your answer be?

"The latter is an exception" isn't helpful and doesn't answer the question. The fact that it doesn't have such an encoding (CPU design) is the exact answer.

The job of an assembler is to translate your mnemonics (e.g. mov eax, ebx) into opcodes and insn encodings. Period. If there's no encoding, how can it translate? Thus it is literally the answer to why "it doesn't compile".

It doesn't answer why it doesn't compile, which is what he asked. Why. Your answer was "because the golden rule blah, with few exceptions".

So if he asks "why does shl eax, cx fail to assemble but shl eax, cl works?" what will your answer be?

"The latter is an exception" isn't helpful and doesn't answer the question. The fact that it doesn't have such an encoding (CPU design) is the exact answer.

The job of an assembler is to translate your mnemonics (e.g. mov eax, ebx) into opcodes and insn encodings. Period. If there's no encoding, how can it translate? Thus it is literally the answer to why "it doesn't compile".

It IS the golden rule of the X86 Instruction Set Architecture (ISA). Both operands must be of the same size! (of course there are a few exceptions).

What, you didn't know this? OMG!! The rule is there ever since 8086 processors! Every single X86 ASM programmers know this simple rule very well!

It IS the golden rule of the X86 Instruction Set Architecture (ISA). Both operands must be of the same size! (of course there are a few exceptions).

What, you didn't know this? OMG!! The rule is there ever since 8086 processors! Every single X86 ASM programmers know this simple rule very well!

That's just your opinion. I don't see any "Golden Rule" in Intel Manuals. You are right that most instructions use the same size for all operands, but that's not the reason why it won't assemble. The pure reason is that an assembler can only assemble instructions which have a valid encoding for the CPU to dispatch.

Intel Manual, in fact, is very formal and lists the encoding exactly and specifies that the operands are both r16/r16 or r32/r32 or r64/r64, etc every single time. There's no "as per golden rule, operands must be the same" assumption. There's no implicit register size anywhere. It is always explicitly shown.

@The_Unknown_Member: bookmark the following site, while it's not as good as official Intel docs, it's good enough to browse (PDF is more of a pain) for quick references: http://www.felixcloutier.com/x86/

That's just your opinion. I don't see any "Golden Rule" in Intel Manuals. You are right that most instructions use the same size for all operands, but that's not the reason why it won't assemble. The pure reason is that an assembler can only assemble instructions which have a valid encoding for the CPU to dispatch.

It Is NOT my opinion. OMG, this guy! Are you even an assembly programmer??

The reason it won't compile is because it violates a SYNTAX RULES of assembly language. It is called SYNTAX ERROR. And the syntax error message from FASM is..

Error: Operand sizes do not match

That's why people call it a "RULE" in laymen's term. My first post in this thread already mentioned that so that a beginner like OP would not be misled by GARBAGE ADVISES from incompetent people like YOU.

This syntax rules is built around the limitation / restriction of x86 architecture - BOTH OPERANDS MUST BE OF THE SAME SIZE, with a few exceptions.

I was talking about the CPU. Did you see the part Intel Manuals? No? Then STFU. The assembler gives you a descriptive error so you know what to fix, it has nothing to do with the reason it won't assemble -- I mean, "syntax" can be altered with macros, so what's your point? You can make "mov eax, bx" assemble if you use a macro. Golden Rule broken? Too bad you won't have a proper encoding to give it (because it doesn't exist).

Stop bothering me with your child tantrums because you didn't get enough attention as a baby.

I was talking about the CPU, moron. Did you see the part Intel Manuals? No? Then STFU. The assembler gives you a descriptive error so you know what to fix, it has nothing to do with the reason it won't assemble -- I mean, "syntax" can be altered with macros, so what's your point?

Stop bothering me with your child tantrums because you didn't get enough attention as a baby.

Calm your tits down. No need for harsh language in here. This is not your thread and we are not your family members where "fcuking" language is part of your family's upbringing.

The rules of the INTEL INSTRUCTION SYNTAX is implemented by the assemblers. So the "OPERAND SIZE MUST OF OF EQUAL SIZE" is not my opinion. So this error message

Error: Operand sizes do not match

is not Tomasz Gryzstar's "opinion" either.

He takes that rules from Intel/AMD. And every single ASM programmers out there know this extremely important rule.

I question your competency to give technical advises to beginners like the OP. You're a big disgrace.

mov ax, bx[/code]It should be 66 89 D8, as you can see it's the same two bytes at end but with a 66 byte prefix in front of it so now it's 3 bytes long, which tells it to use 16-bit operands instead of 32-bit. (this is in 32-bit mode). This is simply how the CPU works, they could've designed it some other way, but it isn't...

No Furs, he's asking a beginner's question. He's probably not interested in listening to GARBAGE like instruction prefixes at this moment. The real reason is SYNTAX ERROR. What error did the code violate?

Operands must be of the same size

You don't have to go to that extra miles extending your GARBAGE to beginners. No, it doesn't make you look any smarter or "important" by doing that. It makes you look desperate.

So you have to "know" if the number stored in bx is signed or unsigned so that you can use the proper extend function to convert it to a full 32-bit value, and then add it to eax.

As for "why" you can't do it with one instruction, the reason is as Furs stated, there is no encoding for it. In theory Intel/AMD could create new instructions "addzx r32,r16" and "addsx r32,r16", but there would be little call for it, and they would mostly go unused, so it is unlikely that we will ever see such instructions.

Just for the OP. List of Rules of the X86 Instruction Architecture and Format.

Rule 1: Both operands must be of the same size (with few exceptions)
Rule 2: Both cannot be memory operands
Rule 3: An immediate cannot be a destination operand

The only "rule" I could agree with here is number 3, since doing such a thing makes no sense. But the first is already broken by the existence of movsx/movzx, and the second is broken by the existence of movs and push [mem]/pop [mem]. For the push/pop case, one of the memory operands is implied/hidden so it is easy to forget that it is really a memory/memory operation. In theory the instruction could be written "mov [--esp],[mem]" which would more clearly indicate the operation (and yes I fully appreciate the irony of using the C construct of -- to illustrate an asm line).

There's actually way more instructions that use a differently-sized operands, especially with immediates. For 64-bit mode with 64-bit operand especially, almost every immediate is actually 32-bit, except for one case of mov (there's also a sign-extended 32-bit immediate to 64-bit register though).

So for example you can't add a huge 64-bit immediate to a 64-bit register directly, unless it fits into a 32-bit signed immediate (because it is sign-extended). There's also the 8-bit sign extended forms, but those won't "fail" to assemble if the immediate is larger though, the assembler will just pick the 32-bit immediate form. There's no 64-bit immediate encoding though, so in that case it *will* fail to assemble.

You cannot post new topics in this forumYou cannot reply to topics in this forumYou cannot edit your posts in this forumYou cannot delete your posts in this forumYou cannot vote in polls in this forumYou cannot attach files in this forumYou can download files in this forum