flat assembler
Message board for the users of flat assembler.

Index > Main > at&t and intel assembly? (three operands, inline asm)

Author
Thread Post new topic Reply to topic
vivik



Joined: 29 Oct 2016
Posts: 671
vivik 09 Dec 2017, 09:12
I understand that the operand order is inversed for them, but what about instructions that have more than 2 operands?

Also I'm confused by inline assembly, the gcc kind. https://en.wikipedia.org/wiki/Inline_assembler . There is a "D language" example there too, but it looks like you can't use it mid function like in C?
Post 09 Dec 2017, 09:12
View user's profile Send private message Reply with quote
vivik



Joined: 29 Oct 2016
Posts: 671
vivik 09 Dec 2017, 10:27
Those two themes (difference between atnt and inline asm, and inline asm) are somewhat related, because it's pretty hard to use intel syntax with gcc. You have to enable intel syntax at the beginning of inline asm, and disable it at the end of it. I guess it's because gcc historically supported more than just intel processors, they don't care about intel enough. And those are the only processors I will ever see.


Last edited by vivik on 09 Dec 2017, 12:03; edited 1 time in total
Post 09 Dec 2017, 10:27
View user's profile Send private message Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 20445
Location: In your JS exploiting you and your system
revolution 09 Dec 2017, 10:31
AT&T syntax ... erm, the less said the better Wink

But seriously, I think just adding a couple of extra lines to enable and disable Intel syntax is a small price to pay for something that is orders of magnitude more readable. IMO of course.
Post 09 Dec 2017, 10:31
View user's profile Send private message Visit poster's website Reply with quote
vivik



Joined: 29 Oct 2016
Posts: 671
vivik 09 Dec 2017, 12:17
If I'll actually make a compiler, maybe I'll be able to fix this "extra lines" situation...

Waiting for answers.

Found those interesting notes on inline asm:

https://dlang.org/spec/iasm.html

https://wiki.dlang.org/LDC_inline_assembly_expressions

https://wiki.dlang.org/Compilers

http://llvm.org/docs/LangRef.html#inline-assembler-expressions
Post 09 Dec 2017, 12:17
View user's profile Send private message Reply with quote
Furs



Joined: 04 Mar 2016
Posts: 2561
Furs 09 Dec 2017, 13:46
First, 3-operand instructions have the operands reversed, so instead of "eax, ebx, ecx" in Intel syntax, it would be "ecx, ebx, eax" in AT&T. There's very few insns with exceptions here (e.g. enter) but I'm not aware of 3-operands exceptions to this rule though.

I don't know anything about D's inline asm, but it looks total shit at a glance, since it copies the one from Visual Studio rather than GCC, which means it doesn't support operand constraints or clobbers which results in trash code. So what's the point of using it if the code is worse than HLL? And if the entire function is in asm, you can just code it in FASM or whatever.

Inline asm is incredibly useful for (forced) inline functions though, but only in GCC since VS generates crap code with it.


What are you confused about GCC's inline asm?

Keep one thing in mind: GCC does NOT parse the asm string and does not understand it. You have to explicitly tell it what the asm does with operands or clobbers. This is great because it allows you to use hacks and "outsmart" the compiler in corner cases, but also because GCC will fully know the intent of the asm if you give the right operands.

Examples:
Code:
asm("movl $5, %%eax")  ; wrong, GCC has no idea you use eax and think this asm doesn't
asm("movl $5, %0":"=a"(some_var))  ; correct, this says "this asm outputs something to some_var, and the constraint says to put it in eax" to GCC    
%0 accesses the "zeroth operand" which in this case is the output operand "=a"(some_var). "=a" is a constraint, it specifies the eax register (or rax, ax, al, depending on size of some_var). "=" says it's an output operand, "+" means it's input/output operand. If we used "add" instead of "mov", we'd have to use +.

The beauty here is that GCC knows that some_var has to be placed into eax before the asm, and the result is also in eax (if we used 'add'), so it generates very good code, unlike Visual Studio.

You can specify more constraints to give it more options, like "=abcd" which lets GCC select any of eax, ebx, ecx, edx registers, depending on surrounding code. Or just "=r" which means any general purpose register.

Also, some registers may not have a constraint associated just with them, you can force them with something like this:
Code:
register int temp asm("ebp") = some_var;
asm("addl $5, %0":"+r"(temp));
some_var = temp;    
This code is optimal: GCC will optimize out all the temporaries here to just direct use of the ebp register.

In GCC, variables don't correspond to a register whatsoever. They only correspond to a register during an inline asm, if you force it that way. Otherwise it's free to remove redundant moves, like in the above example. It actually compiles to just:
Code:
add ebp, 5    
or, if the source was in a different register, it automatically loads it into ebp first, and then does the inline asm. The load into ebp can happen anywhere, since GCC knows about it: it can be scheduled way ahead if it thinks it's optimal.

You should read the GCC documentation about it, since it has far more options and stuff. It even has an "asm goto" when your asm transfers control to somewhere else via a jump or whatever, and yes GCC will know this because you specify the labels as operands, so it will optimize surrounding code and the control flow graph accordingly. That's why GCC's inline asm is superior to Visual Studio and other crappy inline asms.

Just think of operands as the information you tell GCC about the asm. If your asm writes to a register, specify that. If it reads from a register, specify that. If it reads from a specific memory place, specify that. If it clobbers a register (as a temporary), specify that as clobber (read the doc).

Do not use "memory" clobber unless necessary: it tells GCC your asm clobbers ALL memory, so it removes all memory register cache optimizations. If you know what part of memory it accesses, do it like e.g. (assuming p is a pointer to something you write to):
Code:
asm("...":"=m"(*p));  note dereference since you write to the value the pointer points to, not to the pointer itself    



Also D has some nice features I'd like to see in C++ such as "properties", but the C++ committee is full of morons which won't fucking add it already despite the fact it's been requested for ages and also THREE major compilers support it as an extension (but sadly, not GCC, ffs!! Clang, Visual Studio and Intel Compiler all support it as __declspec(property)). I mean GCC C++ maintaners also piss me off a bit because they are so against adding "extensions" to it and want to stick to the shitty standard (which is why I rage at the committee now), while the C front-end guys are much more reasonable and added a ton of extensions. __declspec(property) is a C++ feature though, since it requires C++ classes/structs member functions.

D sucks though, because it has built-in garbage collector which is there even if you turn it off, I'm so sick of that shit really. I'm not against garbage collectors per-se, but rather their forced use on everything, what if I wanted to use a different type of garbage collector? they must be implemented as LIBRARIES or APIs, not BUILT-IN for non-scripting languages, that's downright retarded.
Post 09 Dec 2017, 13:46
View user's profile Send private message Reply with quote
vivik



Joined: 29 Oct 2016
Posts: 671
vivik 09 Dec 2017, 20:59
Thank you.

I wonder, if a good compiler will actually analize the contents of inline asm, without me specifying all that constraint info by hand. I wonder if that's possible.

>I don't know anything about D's inline asm, but it looks total shit at a glance, since it copies the one from Visual Studio rather than GCC

there are three compilers for D, it looks like they implement both ways. I don't know D.

>garbage collection must be implemented as a library

Impossible. Qt tried to do that in C++, and they only archived smart pointers. Compiler should analyze the code and see when the deletion of a variable happens, and also do escape analysis to see if GC is even necessary for a variable. Without it, garbage collection can't be used as a safety net.

>__declspec(property)

Haven't heard about it. Seems like just a syntax sugar, not that necessary... Maybe you can just run a preprocessor on your code? Annoying, I know.
Post 09 Dec 2017, 20:59
View user's profile Send private message Reply with quote
Furs



Joined: 04 Mar 2016
Posts: 2561
Furs 09 Dec 2017, 21:53
vivik wrote:
I wonder, if a good compiler will actually analize the contents of inline asm, without me specifying all that constraint info by hand. I wonder if that's possible.
Well I suppose it's possible but it's less powerful (or quite complicated, imagine using obscure instructions or raw .byte directives?). As far as inline asm, GCC treats the "asm string" as a black box. All it knows about it are inputs, outputs, clobbers, labels, etc.

For example if you push a register and pop it at the end, you usually don't have to specify it as an output or clobber at all, since its value won't change in the asm. (even though it affects the stack, you don't really have to specify that in this case because it doesn't affect any of GCC's code generation, just don't "change" the stack pointer to something else at exit than it was at entry).

Now imagine a compiler actually managing to scan your asm and seeing that the register's value won't change in this particular case. That would mean it has to literally execute the instructions in a virtual machine or something?

BTW: I didn't know this some years ago, but GCC's inline asm is almost directly tied to its internal RTL representation. That's why it's so powerful: its own instructions are represented similarly at the lowest level before they are assembled. An "asm" to GCC looks like just a big "instruction" with specific inputs/outputs/clobbers etc at the RTL level.

vivik wrote:
Impossible. Qt tried to do that in C++, and they only archived smart pointers. Compiler should analyze the code and see when the deletion of a variable happens, and also do escape analysis to see if GC is even necessary for a variable. Without it, garbage collection can't be used as a safety net.
I mean GC like just mark and sweep? Of course, you'll need some metadata to your struct fields and whatnot, I never said you don't need them Wink But at least it's not tied to the language and unable to be changed. If/when C++ adds reflection, this becomes way easier. With builtin garbage collector, you're pretty much stuck though.

vivik wrote:
>__declspec(property)

Haven't heard about it. Seems like just a syntax sugar, not that necessary... Maybe you can just run a preprocessor on your code? Annoying, I know.
Well, C++ itself is syntactic sugar for C code in most cases too Razz

I mean, it's very useful to abstract away field accesses, not just for beautifying code, though I admit, code beauty is one of the reasons I want it. Imagine you're doing a debug build and want to add assertions to a field when it's accessed, to make sure the values fit in a range or whatever condition.

Yeah, you can use a function instead of a field, but beside the fact it's ugly, it changes the API of how you access that field. So code has to be changed, which might not even be mine.

Maybe this struct was a plain simple struct before, just with data. So accessing fields was normal. Now you want to validate its members in debug builds, without changing the syntax (3rd party code or just too much work). Just make the fields properties instead and add the checks, simple and useful. Nothing changes in non-debug builds, since syntax is the same, so you get zero overhead.

That is, if I had this in GCC... Mad

(also, look at the standard library of C++ how many member functions are stuff like size() or begin() or end() and so on, looks like even the committee needs this kind of "functions that should really look like fields")
Post 09 Dec 2017, 21:53
View user's profile Send private message Reply with quote
rugxulo



Joined: 09 Aug 2005
Posts: 2341
Location: Usono (aka, USA)
rugxulo 21 Dec 2017, 00:25
Delphi/FPC has had properties for a while now. I know you prefer C, but keep this in mind. We've discussed languages before, briefly. I think you would appreciate Delphi/FPC if you gave it a chance.
Post 21 Dec 2017, 00:25
View user's profile Send private message Visit poster's website Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  


< 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


Copyright © 1999-2025, Tomasz Grysztar. Also on GitHub, YouTube.

Website powered by rwasa.