flat assembler
Message board for the users of flat assembler.
 Home   FAQ   Search   Register 
 Profile   Log in to check your private messages   Log in 
flat assembler > Main > Why this operation is not possible ?

Goto page 1, 2, 3, 4, 5, 6  Next
Author
Thread Post new topic Reply to topic
The_Unknown_Member



Joined: 28 Aug 2017
Posts: 17
Why this operation is not possible ?
Hi folks. Im wondering why this doesn't work ?

use32 ; x86_32

mov bx, 30d
mov eax, 10d
add eax, bx

What's the problem with this ? Why I can't add the number stored in the 16bit bx register to the number stored in the 32bit eax register and store the result in the eax register ?
Post 28 Aug 2017, 13:04
View user's profile Send private message Reply with quote
Furs



Joined: 04 Mar 2016
Posts: 868
Because the CPU has no instruction that does it. It's just the way it is designed, as it would waste opcode space for no reason (each instruction requires some bytes to identify its "opcode").
Post 28 Aug 2017, 13:10
View user's profile Send private message Reply with quote
The_Unknown_Member



Joined: 28 Aug 2017
Posts: 17

Furs wrote:
as it would waste opcode space for no reason (each instruction requires some bytes to identify its "opcode").



It requires space from the CPU Register's memory or from the RAM ?

Thanks for the answer!
Post 28 Aug 2017, 13:26
View user's profile Send private message Reply with quote
Furs



Joined: 04 Mar 2016
Posts: 868
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 eaxebx

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 axbx

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 Wink).
Post 28 Aug 2017, 13:46
View user's profile Send private message Reply with quote
system error



Joined: 01 Sep 2013
Posts: 667
Re: Why this operation is not possible ?

The_Unknown_Member wrote:
Hi folks. Im wondering why this doesn't work ?

use32 ; x86_32

mov bx, 30d
mov eax, 10d
add eax, bx

What's the problem with this ? Why I can't add the number stored in the 16bit bx register to the number stored in the 32bit eax register and store the result in the eax register ?



It's down to Rule #1 of the X86 architecture: Both operands (source, destination) must be of the same size. There are a few exceptions, but this is the golden rule.

Nothing to do with cache, opcode, instruction length etc.
Post 28 Aug 2017, 14:04
View user's profile Send private message Reply with quote
Furs



Joined: 04 Mar 2016
Posts: 868
"There are a few exceptions" nulls your argument.

See:

Code:
shl eaxcl

which assembles because it has a valid encoding.

It has everything to do with encoding and opcodes and what the CPU is able to dispatch.
Post 28 Aug 2017, 14:12
View user's profile Send private message Reply with quote
system error



Joined: 01 Sep 2013
Posts: 667

Furs wrote:
"There are a few exceptions" nulls your argument.

See:

Code:
shl eaxcl

which assembles because it has a valid encoding.

It has everything to do with encoding and opcodes and what the CPU is able to dispatch.



Thats not nullifying. That CONFORMING to what I meant by a few exceptions.
Post 28 Aug 2017, 14:20
View user's profile Send private message Reply with quote
Furs



Joined: 04 Mar 2016
Posts: 868
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".
Post 28 Aug 2017, 14:27
View user's profile Send private message Reply with quote
system error



Joined: 01 Sep 2013
Posts: 667

Furs wrote:
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! Surprised
Post 28 Aug 2017, 14:35
View user's profile Send private message Reply with quote
system error



Joined: 01 Sep 2013
Posts: 667
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

There are more rules which you can find from Intel/AMD manuals. Stick to them, and you'll be fine. Do not take technical advice from INCOMPETENT people.

Hope this helps Very Happy
Post 28 Aug 2017, 14:44
View user's profile Send private message Reply with quote
The_Unknown_Member



Joined: 28 Aug 2017
Posts: 17
Thanks to all of you for the answers Smile
Post 28 Aug 2017, 16:14
View user's profile Send private message Reply with quote
Furs



Joined: 04 Mar 2016
Posts: 868

system error wrote:
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! Surprised

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/

For example, for MOV: http://www.felixcloutier.com/x86/MOV.html (see there all valid encodings)
Post 28 Aug 2017, 18:47
View user's profile Send private message Reply with quote
system error



Joined: 01 Sep 2013
Posts: 667

Furs wrote:
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. Laughing

And you call yourself an assembly programmer? Surprised
Post 29 Aug 2017, 01:44
View user's profile Send private message Reply with quote
Furs



Joined: 04 Mar 2016
Posts: 868
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.
Post 29 Aug 2017, 13:18
View user's profile Send private message Reply with quote
system error



Joined: 01 Sep 2013
Posts: 667

Furs wrote:
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.
Post 29 Aug 2017, 13:47
View user's profile Send private message Reply with quote
system error



Joined: 01 Sep 2013
Posts: 667

Furs wrote:
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.
Post 29 Aug 2017, 13:53
View user's profile Send private message Reply with quote
Furs



Joined: 04 Mar 2016
Posts: 868
I'm fairly certain he can read english perfectly fine. You know he gets the error too, right? You understand this, right? You're not the only one who can read an error message, shocking I know.

You're so helpful copy pasting a message he is already aware of because he also gets it.

He's obviously asking because he wants to know why the operands must match.


Question: "Why must the operands match [because I get the error]? Why can't I add 16-bit number to 32-bit number?"
Answer: "Because the operands must match!"

Only system error could answer "Why X" with "Because X" (X being same thing).
Post 29 Aug 2017, 13:55
View user's profile Send private message Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 15241
Location: 1I/╩╗Oumuamua
The_Unknown_Member: If you need to add bx to eax you can manually extend it and then add:

Code:
movzx ecx,bx ;zero extend to full 32 bits.
add eax,ecx

;or

movsx ecx,bx ;sign extend to 32 bits
add eax,ecx

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.
Post 29 Aug 2017, 17:28
View user's profile Send private message Visit poster's website Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 15241
Location: 1I/╩╗Oumuamua

system error wrote:
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).
Post 29 Aug 2017, 18:11
View user's profile Send private message Visit poster's website Reply with quote
Furs



Joined: 04 Mar 2016
Posts: 868
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.
Post 29 Aug 2017, 18:52
View user's profile Send private message Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  
Goto page 1, 2, 3, 4, 5, 6  Next

< Last Thread | Next Thread >

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


Powered by phpBB © 2001-2005 phpBB Group.

Main index   Download   Documentation   Examples   Message board
Copyright © 2004-2016, Tomasz Grysztar.