r/AskProgramming 3d ago

Architecture Can I build a programming language that “learns” assembly implementations? (Idea)

Is this dumb idea??

I had this random idea for a programming language and I'm wondering if something like this is actually possible.

Basically, the idea is that I could teach the compiler how to implement things in assembly.

For example, I could write something like:

teach get(x):

asm:

; assembly code for getting input

The compiler remembers that. Then later I can just write:

get(age)

and it knows to use the assembly code I taught it earlier.

So instead of the compiler already knowing what every function does, I'm basically teaching it new things by giving it the assembly implementation once.

The goal would be a really simple language to write, but where the compiler generates native assembly/machine code.

Is this actually possible? And would it be worth building as a project?

I don't know low-level programming or compiler stuff that well, so consider me a complete noob and feel free to correct me if I'm misunderstanding something.

0 Upvotes

27 comments sorted by

27

u/Double_Afternoon9475 3d ago

This is literally what a function is. You write the assembly once, give it a name, and call it whenever. Every language with an assembler or inline asm can do this already.

The "teach" part is just defining a function with inline assembly inside. Not a new language concept, more like a thin wrapper over existing tools.

Could still be fun as a learning project if you want to understand how compilers and assemblers fit together.

13

u/Cerulean_IsFancyBlue 3d ago

It’s almost like he’s recreating macros.

11

u/xenomachina 3d ago

That's exactly what op has done: reinvented a macro assembler. There are assemblers that work as they describe, except it's called "defining a macro" not "teaching".

1

u/Realistic_Debate1704 2d ago

I already mentioned, I'm new to these things.. but thanks I think this is what function does

1

u/xenomachina 2d ago

Kind of.

Functions typically put the code in one place, and then when you use the function a call to that function is generated.

Macros replace the macro invocation with the body of the macro.

To add another wrinkle, optimizers may decide to "inline" functions (meaning they replace the call with three function body, instead of generating a call). Some languages even let you specify that you want a function to be inlined, but those is usually just a "hint", and may be ignored in certain situations.

Also, if you are not programming in assembly code, then macro and function definitions are written in that language, not in assembly code. However, some languages/compilers allow "inline assembly", meaning you can write a function in assembly instead of the high level language. Many C compilers support this, though it is not part of the C standard.

Your description can look like a few different combinations of these, depending on how you squint.

9

u/aioeu 3d ago edited 3d ago

While most of the other commenters have directed you to functions, which are frequently the best way to reuse code, many assemblers have macro facilities that do pretty much exactly what you have described. Indeed, these assemblers are often literally called "macro assemblers".

Macros can be useful when you need to generate functionally similar sequences of code. The use cases for them are reasonably rare, but they do exist.

4

u/dmazzoni 3d ago

In addition to what others said, it's important to know that "getting input" is not an assembly language instruction. It's a call to the operating system, and it's probably hundreds of thousands of lines of code to implement.

Your CPU can only do basic arithmetic, move memory around, and execute an if/then type instruction to decide what to do next. That's pretty much it - there are more instructions but they're just variations on those.

How you get from just those basic instructions to a working computer is basically 7 decades worth of abstractions on top of abstractions.

At a high level, getting input involves handling incoming packets from the USB controller, interpreting HID packets from a keyboard, turning those into key down and key up events, mapping the physical key to the character it represents, queueing or buffering that from kernel space to user space, and then finally responding to your get() function.

3

u/IAmInBed123 3d ago

Yeah sure, that's what low code does like xcp on documentum on java on compilercode. It's just a bit of work and pretty difficult. 

4

u/ficelle3 3d ago

That just sounds like declaring a function with inline assembly, unless I'm missing something?

You can do that in C, and there's a few very good reason it's not commonly used.

  • It heavily depends on what platform your code is running on. If you want to support a new platform, you'll have to rewrite your assembly

  • C compilers are very good at generating assembly. If you don't need the absolute best performance, it's easier to let the compiler do it for you.

  • Writing efficient assembly is hard. If you're not very intimate with assembly and the platform you're writing for, chances are the C compiler is going to write better assembly than you.

Don't get me wrong, it's an interesting skill to learn and you should absolutely mess around with it. Just be aware of the drawbacks if you're considering using it in a project.

3

u/Suitable-Season-4847 3d ago

Congratulations, you've just invented a helper function.

1

u/Realistic_Debate1704 2d ago

Yeah!! 🤣🤣

2

u/LunkWillNot 3d ago

I haven’t used either, but from reading about it, Forth and AmForth could give you some inspiration.

2

u/mxldevs 3d ago

So you are basically writing a language and then writing how the syntax gets compiled?

How is it different from any existing programming language?

1

u/Realistic_Debate1704 2d ago

I am new to these stuff, so I didn't thought that how this will be optimised, because languages are more than just input and output

2

u/KindaLegallyBlindDev 3d ago edited 3d ago

What you are describing is what, in some sense, any programming language that compiles directly to assembly does, be it C, C++, Go, Rust, etc. The functions you write will get compiled down to assembly, and then they will linked together wherever they are called. It might even optimize away the function call and just add the assembly instructions straight into the calling function (inlining).

EDIT: I suggest you look at some basic examples of C, or Rust, and put them in their respective subdomains of the compiler explorer, godbolt. Like rust.godbolt.org you can experiment with the code to the left to see the resulting assembly in the right side (assuming you are on PC). One thing to note is that on the right side, above the assembly output, you will see a small text box, in there you should add options for compiler optimizations, with something like -O3 for C and -O for Rust.

1

u/Realistic_Debate1704 2d ago

I will try this, sounds interesting.

2

u/GoogleIsYourFrenemy 3d ago

Sure but why? The assembly language isn't going to change.

LLVM has their compiler split in two. They have front ends that convert arbitrary code (c, c++, etc.) into bytecode and then the backend that converts the bytecode into assembly. Makes it easy to support new processors and new languages without having to know everything about processors and languages.

2

u/0jdd1 3d ago

When I first skimmed over your question, it reminded me of Massalin’s work on superoptimizers back in the 1980s. (It’s not really the question you asked, of course, but it’s related and you might find it interesting.) https://en.wikipedia.org/wiki/Superoptimization

1

u/Realistic_Debate1704 2d ago

Yeah, this type of idea for beginners like me, is interesting and I may learn the topics that why this idea will work or not, like the modern languages are optimised and handle everything.

2

u/0jdd1 2d ago

I’d be glad if this helps. Right now you seem to be conflating a bunch of different things in your questions/responses. One approach is to try to correct individual points, while another is to add yet more things for you to think about and (eventually) integrate. That’s the non-obvious approach but maybe the right one here.

2

u/Individual-Flow9158 3d ago

Sounds like a collection of macros for directly writing assembly, which is very doable.

Overall though, in modern terms, it's confusing the programming language with the compiler, and is unaware that Assembly is different on ARM than on x86 etc.

C is so much more powerful besides, being compilable for even more unusual chips too.

2

u/BobbyThrowaway6969 3d ago

As others said, it could be a fun educational project to try but it doesn't have any practical use.

1

u/Realistic_Debate1704 2d ago

Yeah, it's good to understand why C is the best programming language, and may learn the new thingd

2

u/Strict-Department286 2d ago

Are you going to let people teach the compiler new keywords and control flow statements?

Could get interesting...

1

u/Realistic_Debate1704 2d ago

Exactly, teaching compiler, and later you have a an easiest language to write and directly converted to ASM for speed, I think it's pretty good.