Assembly, C++ and a little more...

Pages: 12
closed account (43RGz8AR)
I thought I might ask what the C++ community thinks about the relationship between the C++ standard and assembly. Yes I'm talking generally about assembly, but I've always wondered why there isn't a standard way about it yet it can be "Inlined" with C/C++. I my self love low level code, and I love to play with C++ and Assembly. I have used GAS, NASM, and FASM in the past as well as attempted to build my own assembly language and/or compiler (I didn't really have the time or effort/patience for it). I stayed with FASM in the end, but I come to wonder why we can't have a standard or shared way for assembly syntax. I resonantly found a couple places through out a API-like project and thought this would be so much easier if I could just use some assembly instructions instead of using these OS and compiler dependent functions.

Just to expand on what I'm talking about. The C++ standard I assume to be standardized so that across all platforms base code can be relatively the same. If this is true then I believe the C++ standard has failed. Instead we have low level compiler function extensions (__builtin_*) and different syntax for inline assembly. I think we should at least have a new standard library for these low level functions so they can be across platform a little easier. It maybe that this field doesn't get much attention sense agreeably you can avoid assembly almost all the way in drivers and OS low level. I find a lot of upper level programmers truly miss the power and simplicity of some extended instructions sets AVX, SSE and the like. In C++ in a 64bit platform the max general integer you can use is long long yet in the spec of AVX you can address up to 256bit values. Now I may not be completely right as I did not read all of Intel's spec sheets on the topic. Just looking for what you guys think, and solutions always welcome.

(Sorry working on my English skills)
Last edited on
What's the point of standardizing for portability something that by definition is not portable?
The C++ standard can't dictate a standard for inline assembly syntax for every imaginable CPU architecture that exists, much less for those architectures that have yet to come. "Cross-platform" and "inline assembly" are mutually exclusive.
For the things that matter (SSE and AVX) there are standardized intrinsics.
closed account (43RGz8AR)
I believe most CPUs allow checking if instruction set are valid. Portability between platforms is not completely optimal, I never said assembly is completely portable. My complaint, I guess, is with how the syntax is not entirely what instructions are used.

EDIT: My suggestion, if any, is that C++ standard should ether include rotation, endianness functions, and the like of more powerful/useful instructions. To accompany for the very much widely supported rotation instructions, like what GCC already has put into effect and then in that they can provide the alternative C++ ways of doing it without hardware support. Or provide a standard assembly syntax.
Last edited on
"The portability of Assembly is not completely optimal" must be the understatement of the century. Assembly is not portable, period. You can't take a C source with inline Assembly for x86 and expect it to compile and run on a SPARC.
If you want to include assembly in your C++ programs and maintain portability, don't use inline assembly. Write C++ header files for your assembly functions and then put the assembly functions in separate source files in a folder called something like src/arch/<platform>. Then put your C++ source files in src/common/.
closed account (43RGz8AR)
"The portability of Assembly is not completely optimal" must be the understatement of the century. Assembly is not portable, period.
That is not entirely true. x86_64, x86 and Intel's original 16 IS is still the dominate assembly play ground and even if its not do you think someone working on the less used IS is really going to use anything but assembly for the basics to build on top of with a higher language. Funny enough I have found quite a share of slow C++ library functions that could vary much be replaced with portable assembly.
I think you missed the second half of my post. I'll just repeat it here, in different words: x86 and x86-64 are not the only architectures that exist.
For example: http://en.wikipedia.org/wiki/List_of_Linux_supported_architectures

There's not just one Assembly language. There's one for each CPU architecture. x86 Assembly is completely different from MIPS Assembly and from SPARC Assembly, and they're all different from ARM Assembly.
Last edited on
closed account (43RGz8AR)
I know that they are way more then a couple instruction sets out there. I've written assembly for ARM, x86, and couple more. The general target for me is x86 and its brothers, like a lot of developers that's all I meant in that. Speaking of missing posts I'm not sure your cot my edit of my first reply as you posted at the same time nearly.
I have found quite a share of slow C++ library functions that could vary much be replaced with portable assembly.

I have a far better idea: replace them with fast C++ code that is really portable.
I'd like to point out that the code the compiler generates is often a lot faster than hand-written inline assembly (unless you actually know what you're doing). Using inline assembly to speed things up might have been a good idea 20-30 years ago. Today, it rarely is.
Last edited on
closed account (43RGz8AR)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
#ifndef __GNUC__
#define __GNUC__ 0
#define __GNUC_MINOR__ 0
#endif

#if __GNUC__ >= 4 and __GNUC_MINOR__ >= 3
// This only works with version 4.3 and greater.
// GCC IS

	void API WordSwap(uint16* w) {
		*w = (uint16)__builtin_bswap32( (int32_t)*w );
	}
	void API DwordSwap(uint32* d) {
		*d = (uint32)__builtin_bswap32( (int32_t)*d );
	}
#ifdef SYS_X64
	void API QwordSwap(uint64* q) {
		*q = (uint64)__builtin_bswap64( (int64_t)*q );
	}
#endif

#elif defined( _MSC_VER )
// VC++ IS
#include <intrin.h>

	void API WordSwap(uint16* w) {
		*w = _byteswap_ushort(*w);
	}
	void API DwordSwap(uint32* d) {
		*d = _byteswap_ulong(*d);
	}
#ifdef SYS_X64
	void API QwordSwap(uint64* q) {
		*q = _byteswap_uint64(*q);
	}
#endif

#else
// Manual
	void API WordSwap(uint16* w) {
		*w = ((*w & 0xff00U) >> 8) + ((*w & 0x00ffU) << 8);
		return;
	}
	void API DwordSwap(uint32* d) {
		*d = ((*d & 0xff000000UL) >> 24) + ((*d & 0x00ff0000UL) >> 8)
		     + ((*d & 0x0000ff00UL) << 8)  + ((*d & 0x000000ffUL) << 24);
		return;
	}
#ifdef SYS_X64
	void API QwordSwap(uint64* q) {
		*q = ((*q & 0xff00000000000000ULL) >> 56)  + ((*q & 0x00ff000000000000ULL) >> 48)
		     + ((*q & 0x0000ff0000000000ULL) >> 24)  + ((*q & 0x000000ff00000000ULL) >> 8)
		     + ((*q & 0x00000000ff000000ULL) << 8)   + ((*q & 0x0000000000ff0000ULL) << 24)
		     + ((*q & 0x000000000000ff00ULL) << 48)  + ((*q & 0x00000000000000ffULL) << 56);
		return;
	}
#endif

#endif 

Best example I could find right off the bat. Any one else think that sucks.
The general target for me is x86 and its brothers, like a lot of developers that's all I meant in that.
Unfortunately for you, the C++ committee's aim for portability is broader than that. Wise, in my opinion.

My suggestion, if any, is that C++ standard should ether include rotation, endianness functions, and the like of more powerful/useful instructions.
This kind of sub-micro-optimization is for the most part pointless at the C/++ level. If you're spending a considerable amount of time thinking about stuff like this, you're not using the right language.

Or provide a standard assembly syntax.
It's not possible to provide a standard anything for something that's not standardized in any way. Unless you want something that can be translated to different Assemblies at compile time. That thing is C.

EDIT: You're complaining about that? Pfft. That's nothing. There's a portable way of swapping bytes that works everywhere. What more could you ask for? Try finding something like that to open a file with a Unicode name and addressing it with 64-bit offsets.
Last edited on
Yes, it does suck. Byte swapping is actually one of the few cases where I've used inline assembly/intrinsics.
Edit: and then removed it later, I should mention. gcc recognizes bitshifting code that swaps bytes and uses a bswap instruction automatically.
But I think you got carried away a bit here - what you actually want is a byte swapping function in the C++ standard library, not "portable inline assembly".
Last edited on
closed account (43RGz8AR)
(Okay this will be my last reply for the night)

Obliviously you have no idea what I mean by "Or provide a standard assembly syntax."
FASM and NASM have it this way.

1
2
3
; comment
mov eax, 0
; same as eax = 0


GAS/AT&T
 
mov $0x05, %eax


is the same binary code instruction but written two different ways.
Last edited on
closed account (1vRz3TCk)
Obliviously you have no idea what I mean by "Or provide a standard assembly syntax."...
is the same binary code instruction but written two different ways.

So the assemblers have different syntax, what has that got to do with C++?

Edit:
unless you are talking about an abstracted assembly language that is mapped to a specific assembler syntax by the compiler implementor ... but then you would/could not have a one to one mapping making it pointless.
Last edited on
closed account (43RGz8AR)
what the C++ community thinks about the relationship between the C++ standard and assembly.


Everyone here seems to have missed the point of this post.

@Athar thank you for contributing to the real topic, at least in part. Opening topic:
I think we should at least have a new standard library for these low level functions so they can be across platform a little easier.


EDIT: My suggestion, if any, is that C++ standard should ether include rotation, endianness functions, and the like of more powerful/useful instructions. To accompany for the very much widely supported rotation instructions, like what GCC already has put into effect and then in that they can provide the alternative C++ ways of doing it without hardware support.


@CodeMonkey Must I really need to point up to the opening topic again?

@Helios I am giving you and others information about the background of this topic.
Unfortunately for you, the C++ committee's aim for portability is broader than that. Wise, in my opinion.

This kind of reply helps no one. Another topic I could bring in is that C++ standard aims to fit all but a lot of the time it doesn't come close. Lets face it there is not much you can write with just the standard libraries that work on all platforms if you want to go farther then printing text to a console. An assembly standard would only fit into how general instructions are use and macro type stuff. Extensions and other instructions of different platforms would come and go accordingly, but so does everything else with C++ (WinAPI and the alike). I don't view this as a bad thing because obliviously adding something like that only brings C++ one step closer to something like Java. The only point I originally had in mind from this second option is would it/could it be a good thing to have inline assembly that would share a syntax inside of C++. Example:
1
2
3
4
5
6
7
8
9
10
// Something like this
asm {
[x64]
[protected]
; comments
DwordSwap:
bswap ebx
mov eax, ebx
ret
}

Yes its platform dependent but how many functions do we write in C++ that aren't (from a API level of course)?

By the way to point out that list you gave before only had half of it's size made out of real base instruction sets. Things like AVX, SSE are extensions not bases, ARM, RISC, and IA32 are bases. Also to some degree an assembler does replace typed instructions with the one binary code for the platform. Move and jump instructions vary but the name and syntax in the assembly stay the same.

This kind of sub-micro-optimization is for the most part pointless at the C/++ level. If you're spending a considerable amount of time thinking about stuff like this, you're not using the right language.

My reasoning for thinking about these things is explained I think in me saying I like low level programming. If I'm building a compiler I want to know exactly what it is doing only so to better optimize what binary it gives out. It also brings up that "little old thing" of how much do you trust your compiler to make the right choice for you. I understand that if you wanted it done completely right you are stuck with assembly. (This is going a little far off what I planed to gain from this discussion.) Compilers should be optimized to the point that from higher levels you shouldn't need to worry about it, but for a cutting edge programmer you cannot rely on compilers to catch up so quickly. Some of them take years. Also I haven't found many/any programming languages that offer the best of low level while jumping above like C/C++ with assembly can do.
closed account (1vRz3TCk)
Xenouis wrote:
@CodeMonkey Must I really need to point up to the opening topic again?
Hmm. you made a statement and I asked a question for clarification.


Xenouis wrote:
I could bring in is that C++ standard aims to fit all but a lot of the time it doesn't come close.
No, the standard aims to say what is available in all implementations, anything else should be done by extension. Every thing about how the vendor implements the standard is up to them

Xenouis wrote:
An assembly standard would only fit into how general instructions are use and macro type stuff.
I'm still not sure what you want to standardise. If you want to standardise the syntax of assembly languages, then it has nothing to do with the C++ standard. If you are talking about adding a 'general assembly language' to C++, then ... to put it bluntly, that's just dumb for so many reasons mainly to do with defeating the object of having embedded assembly.

closed account (43RGz8AR)
Up in my opening I stated
Yes I'm talking generally about assembly, but I've always wondered why there isn't a standard way about it yet it can be "Inlined" with C/C++.

I thought that would of clarified your question. I also just wanted any other random feed back about the relationship of assembly and C/C++. Like do you use it, should it exist, do you think something about it should be changed, have a better solution to low level programming (probably related to assembly)?

No, the standard aims to say what is available in all implementations, anything else should be done by extension.

Far enough I stand corrected :)

Okay CodeMonkey enlighten me on why that's so dumb?
A portable assembly language cannot exist. The examples you posted are merely two different syntaxes for the same architecture (x86 or the like).

If you wish the C++ standard to be changed then you are at the wrong place. If you are yourself a programmer, then why don't you invent a portable assembly syntax and incorporate it into C++? You claim to have enough knowledge on that. It shouldn't be too difficult, if you truly know what is to be obtained.
Why bother? C is essentially "portable assembler" and can be linked almost effortlessly with C++ programs.
Pages: 12