flat assembler
Message board for the users of flat assembler.
![]() Goto page 1, 2, 3, 4, 5, 6 Next |
Author |
|
Furs 28 Aug 2017, 13:10
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").
|
|||
![]() |
|
The_Unknown_Member 28 Aug 2017, 13:26
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! |
|||
![]() |
|
Furs 28 Aug 2017, 13:46
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 Now try: Code: use32
mov ax, bx 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 ![]() |
|||
![]() |
|
system error 28 Aug 2017, 14:04
The_Unknown_Member wrote: Hi folks. Im wondering why this doesn't work ? 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. |
|||
![]() |
|
Furs 28 Aug 2017, 14:12
"There are a few exceptions" nulls your argument.
See: Code: shl eax, cl It has everything to do with encoding and opcodes and what the CPU is able to dispatch. |
|||
![]() |
|
system error 28 Aug 2017, 14:20
Furs wrote: "There are a few exceptions" nulls your argument. Thats not nullifying. That CONFORMING to what I meant by a few exceptions. |
|||
![]() |
|
Furs 28 Aug 2017, 14:27
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". |
|||
![]() |
|
system error 28 Aug 2017, 14:35
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". 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! ![]() |
|||
![]() |
|
system error 28 Aug 2017, 14:44
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 ![]() |
|||
![]() |
|
The_Unknown_Member 28 Aug 2017, 16:14
Thanks to all of you for the answers
![]() |
|||
![]() |
|
Furs 28 Aug 2017, 18:47
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). 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) |
|||
![]() |
|
system error 29 Aug 2017, 01:44
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. ![]() And you call yourself an assembly programmer? ![]() |
|||
![]() |
|
Furs 29 Aug 2017, 13:18
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. |
|||
![]() |
|
system error 29 Aug 2017, 13:47
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? 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. |
|||
![]() |
|
system error 29 Aug 2017, 13:53
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... 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. |
|||
![]() |
|
Furs 29 Aug 2017, 13:55
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). |
|||
![]() |
|
revolution 29 Aug 2017, 17:28
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 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. |
|||
![]() |
|
revolution 29 Aug 2017, 18:11
system error wrote: Just for the OP. List of Rules of the X86 Instruction Architecture and Format. |
|||
![]() |
|
Furs 29 Aug 2017, 18:52
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. |
|||
![]() |
|
Goto page 1, 2, 3, 4, 5, 6 Next < Last Thread | Next Thread > |
Forum Rules:
|
Copyright © 1999-2025, Tomasz Grysztar. Also on GitHub, YouTube.
Website powered by rwasa.