That's what you are doing.
You are thinking in assembler and implementing in C finally to increase portability of the assembly.
An idea is that you could create macros to select the size of data automatically depending whether the program is compiled for 16, 32 or 64 bits, and it would make your code portable further as now you won't need to change offset macros just for a global change in machine word size.
C and the GNU assembler: how to deal with structs?
Re: C and the GNU assembler: how to deal with structs?
YouTube:
http://youtube.com/@AltComp126
My x86 emulator/kernel project and software tools/documentation:
http://master.dl.sourceforge.net/projec ... ip?viasf=1
http://youtube.com/@AltComp126
My x86 emulator/kernel project and software tools/documentation:
http://master.dl.sourceforge.net/projec ... ip?viasf=1
Re: C and the GNU assembler: how to deal with structs?
I wouldn't go around assuming what other people are thinking. Unless you can read minds, you're liable to offend people.~ wrote:You are thinking in assembler and implementing in C finally to increase portability of the assembly.
Besides, the above is not a good strategy. C is not a high-level assembler. You do things very differently between the two. Reading long disassembly listings, I find I'm having trouble understanding loops, when in C there's no issue at all. On the contrary, I'm often thinking in C even when I have to implement something in assembler.
And the different architectures are not just different in word size. AMD64 and i386 have completely different ABIs. Not to mention the fact that some of us might have the ambition to one day branch out beyond the PC. Good luck writing your macros so they can accommodate PowerPC.
Carpe diem!
Re: C and the GNU assembler: how to deal with structs?
I always keep my OS code ready to be assembled to 32 and 64-bit modes (I check it often), even to 8088 and 386 16-bit. Anything that doesn't assemble or throws a warning, is a way to improve my code a big step more, as it lets me see what isn't really well thought in code, and just make it portable (for example use 0xFFFFFFFF instead of -1 as choosing between something like EAX and RAX without being absolutely specific will become nonportable).
Non-portable instructions like PUSHA/POPA can also be resolved through macros across all modes to generate compatible code instead without leaving it abandoned.
So the only thing left is separating the code into the parts that are just not portable across modes but that can be selected for each one; and the code that is so generic that can be ported with automatic macros to 16, 32 or 64-bit modes with absolutely no modifications (most of the code is like that); even to other platforms.
To take assembler portability beyond the PC, I plan to take the CPU instruction syntax and overall machine platform structure of my preferred architecture to any other as the absolute minimum that must always be present to recycle my work infinitely.
Non-portable instructions like PUSHA/POPA can also be resolved through macros across all modes to generate compatible code instead without leaving it abandoned.
So the only thing left is separating the code into the parts that are just not portable across modes but that can be selected for each one; and the code that is so generic that can be ported with automatic macros to 16, 32 or 64-bit modes with absolutely no modifications (most of the code is like that); even to other platforms.
To take assembler portability beyond the PC, I plan to take the CPU instruction syntax and overall machine platform structure of my preferred architecture to any other as the absolute minimum that must always be present to recycle my work infinitely.
YouTube:
http://youtube.com/@AltComp126
My x86 emulator/kernel project and software tools/documentation:
http://master.dl.sourceforge.net/projec ... ip?viasf=1
http://youtube.com/@AltComp126
My x86 emulator/kernel project and software tools/documentation:
http://master.dl.sourceforge.net/projec ... ip?viasf=1
Re: C and the GNU assembler: how to deal with structs?
I'm certainly no expert at assembly but I doubt this strategy will work. There is no standard for defining what instructions an ISA may have. You cannot make macros that can handle every possible architecture you plan to port your code to, and you can't 100-percent guarantee that an instruction will be present on another platform, even if it is virtually the 'standard'. Platforms are allowed to define any instruction they so please -- and even make those instructions do whatever they want.~ wrote:I always keep my OS code ready to be assembled to 32 and 64-bit modes (I check it often), even to 8088 and 386 16-bit. Anything that doesn't assemble or throws a warning, is a way to improve my code a big step more, as it lets me see what isn't really well thought in code, and just make it portable (for example use 0xFFFFFFFF instead of -1 as choosing between something like EAX and RAX without being absolutely specific will become nonportable).
Non-portable instructions like PUSHA/POPA can also be resolved through macros across all modes to generate compatible code instead without leaving it abandoned.
So the only thing left is separating the code into the parts that are just not portable across modes but that can be selected for each one; and the code that is so generic that can be ported with automatic macros to 16, 32 or 64-bit modes with absolutely no modifications (most of the code is like that); even to other platforms.
To take assembler portability beyond the PC, I plan to take the CPU instruction syntax and overall machine platform structure of my preferred architecture to any other as the absolute minimum that must always be present to recycle my work infinitely.
Re: C and the GNU assembler: how to deal with structs?
I'd be interested to see how your paging code assembles on an 8088.
Re: C and the GNU assembler: how to deal with structs?
Well, OK, so for one thing, you have no way to take advantage of different register files (you do know AMD64 has sixteen GPRs, right? And PowerPC has 32), it also could only possibly come into usefulness for portable code. That is, all the stuff you might reasonably use C for. Assembler is generally used for the unportable stuff, and even there, a lot can be done in C.~ wrote:I always keep my OS code ready to be assembled to 32 and 64-bit modes (I check it often), even to 8088 and 386 16-bit. Anything that doesn't assemble or throws a warning, is a way to improve my code a big step more, as it lets me see what isn't really well thought in code, and just make it portable (for example use 0xFFFFFFFF instead of -1 as choosing between something like EAX and RAX without being absolutely specific will become nonportable).
Non-portable instructions like PUSHA/POPA can also be resolved through macros across all modes to generate compatible code instead without leaving it abandoned.
So the only thing left is separating the code into the parts that are just not portable across modes but that can be selected for each one; and the code that is so generic that can be ported with automatic macros to 16, 32 or 64-bit modes with absolutely no modifications (most of the code is like that); even to other platforms.
To take assembler portability beyond the PC, I plan to take the CPU instruction syntax and overall machine platform structure of my preferred architecture to any other as the absolute minimum that must always be present to recycle my work infinitely.
So, I guess what I'm asking is: Did you just re-invent a high-level assembler? Because C started with that idea in the late 70ies and look where it is now.
Carpe diem!
Re: C and the GNU assembler: how to deal with structs?
Lots of people love to think of C as a high-level assembler, (including myself,) but it started out with modifications of an interpreted language. Around 1969, Ken Thompson took BCPL and adapted it to his minimalist tastes, producing B. Using B, Thompson, Dennis Ritchie, and others found certain tasks would be much more convenient with a type system, and I guess they wanted the performance of a compiled system, so Ritchie produced the first C compiler. I don't think Unix was translated to C for 2 or 3 years. (Somewhere, I have a copy of Ritchie's own writings on the origin of C. I'll share it when I find it.)nullplan wrote:So, I guess what I'm asking is: Did you just re-invent a high-level assembler? Because C started with that idea in the late 70ies and look where it is now.
I guess the tradition of using C as a high-level assembler took shape in the 80s & 90s with the slow conversion of assembly-language programmers to C. I know many programmers didn't want to convert, thinking all high-level languages hopelessly inefficient for the small computers they worked on. Change happened inexorably, Fortran C and Pascal displaced assembler, and C displaced the other two, perhaps because it's more structured than Fortran and more low-level than Pascal. Fortran's lack of structure made it the bad boy of the bunch, but it was for a time considered the fastest language. Pascal was just too prissy; "Real programmers don't eat quiche." All along, a major driving force was the connection in the minds of many programmers between low-level coding and efficiency, which was a very strong belief whether it was true or not. The belief was no doubt reinforced by the obvious gross inefficiencies of so much 90s software. Here's an interesting article on the inherent inherent inefficiencies of object-oriented languages. In the 90s, ignoring these problems, OO became a sort of God worshipped for the wonderous benefits it would miraculously bestow. In some circles you couldn't speak a bad word about OO! Of course, Real Programmers couldn't stand it, but, distrusting this ridiculous propaganda, they kept to their own doctrine of low-level = good, and made C fit their purposes. They needed a high-level language, even a structured one, because they're writing more complex programs for more complex machines, but hardcore subcultures keep the hardcore spirit. (I'm looking back as someone who was recently a member of such a subculture. ) It's funny how the roots of the subculture have been forgotten; they once considered both C and Unix as bloated and slow.
Anyway, I think I've drifted way off topic even though I'm not sure what the topic even is any more! I do know that some of the points raised on the original topic made me worry, possibly without reason. You just have to know the ABI your compiler conforms to, don't you? Given that, you could easily generate offsets from the C struct declaration. Write a script in Perl or whatever, run it from the makefile... Any thoughts of portability here merely consist of supporting the various different ABIs your compilers may produce, not some mystic version of "code quality".
Kaph — a modular OS intended to be easy and fun to administer and code for.
"May wisdom, fun, and the greater good shine forth in all your work." — Leo Brodie
"May wisdom, fun, and the greater good shine forth in all your work." — Leo Brodie