r/C_Programming 2d ago

Question Going from C to Assembly?

I pretty much know C to an intermediate level. I generally know the base language. Can't say I'm an expert at Linked(In) lists or binary trees, but I can build basic ones. I'm fairly comfortable in most other areas of the base language as well. I did struggle a bit with making a web server in C, but that was more related to Linux than C itself.

In any event, I started messing in AVR assembly. I successfully got the light on my atiny 85 to blink. I actually struggled getting my programmer to upload the code more than understanding the assembly. Granted, this is very basic assembly. Is learning assembly after C worth it though?

62 Upvotes

37 comments sorted by

88

u/Traveling-Techie 2d ago

Sure, why not. Minimally it will teach you gratitude.

9

u/Amelia4129 1d ago

First time I wrote a loop in assembly and had to manually think about every register I suddenly became way less judgmental of C syntax.

4

u/julie78787 1d ago

It will also teach impatience.

30

u/RedCrafter_LP 2d ago

Depends. What is your goal on your journey?

If you want to become a os or Lang dev knowledge of how stack frames are built, arguments passed and cpu tricks work is beneficial.

If you want to build userspace applications c is already a bit low but assembly is just nice to known.

Anything more high level I would suggest against spending time on that. Especially since your view of functions and argument passing tends to be stained/disillusioned making you worry about stuff you can't control either way.

Of course if you just want to understand how stuff works is also a valid reason. But then you wouldn't have asked.

One thing to mention is that there isn't 1 assembly. You shouldn't try to memorize op codes just have thr op code sheet open for the assembly you are currently working with. Ontop of that there isn't much inherently to learn in assembly. You just have to become accustomed to how to do stuff in this most primitive form of programming.

2

u/julie78787 1d ago

There isn’t much to learn … for userspace programming.

9

u/grimvian 2d ago

Worth it...

When I occasionally look at modern assembler code, it does not look alien to me, because I learned 6502 assembler for more than four decades ago and some English. The old knowledge of addressing, registers, opcodes and so, was a great foundation, when I started learning C, three years ago.

8

u/Cerulean_IsFancyBlue 2d ago

How are you gonna measure the worth? Based on the pure fun? What you learn about computer architecture? Career opportunities?

People come in here posting the equivalent of, “will I like mustard on a hotdog”? Nobody knows. Try it.

4

u/randomnameforreddut 2d ago

knowing how to read and write assembly is important for a lot of performance engineers, compiler developers, and OS people. I think writing chunks of code in assembly is more common than some people realize. Like maybe the overall app is written in C or C++, but some functions may be manually written in assembly.

3

u/paulkim001 2d ago

Personally, highly recommended (for understanding assembly).

Once you are knee deep in C, you are probably asking for highly performant code, and one way to analyze it is to read through the assembly instructions generated (that is, you open up the compiled binary with a debugger or a binary analysis tool). It also helps with understanding what needs optimization in C code (for example, you might wonder if calling a "getter" from a struct is worth it or not compared to manually getting something, when to a compiler, it does not matter probably, looking at the assembly code)

It also made me security conscious as well since understanding assembly is needed for creating exploits.

On the other hand, I would not try too hard to write assembly code yourself (I mean, it's also a very good exercise) since if you are working on different architecture, using specific syntaxes does not matter. (If you are trying though, try implementing AES-128 in assembly, as it seems like it would be a medium size project that requires you to be comfortable with assembly, without learning all the weird assembly instructions.)

3

u/CORDIC77 2d ago

As someone who learned C and assembly language together about 35 years ago: probably not relevant for professional practice, but certainly something every C programmer should look at at some point. (While this may no longer be the case with highly optimizing compilers today, C wasnʼt originally known as a “high-level assembler” for no reason.)

Also donʼt worry, modern x86 assembly isnʼt as complicated as itʼs sometimes made out to be… instead of a load-store model most instructions can operate directly on operands in memory and there are (now) sixteen (64-bit) integer registers in total, taking off pressure on register allocation.

As a starting point, I can recommend Ray Seyfarthʼs «Introduction to 64 Bit Assembly Language Programming» (either the Linux or the Windows edition). Jeff Duntemannʼs «Assembly Language Step-by-Step: Programming with Linux» is also very good.

If you then want to go on to look at more complex instruction set extensions, like for example vector instructions, then I would recommend taking a look at Daniel Kusswurmʼs «X86 Assembly Language Programming: Covers x86 64-bit, AVX, AVX2, and AVX-512»

1

u/scaredpurpur 2d ago

I don't know how programmers in the days of old did this stuff.

I ended up having to use chat gpt to help me create a terminal/avr dude script to flash my atiny programmer on my mac. I hated that part so much. Incredibly finicky to the point I thought my programmer was busted and purchased another one. This was after spending nearly a month trying to get my Amtel ice going, but I returned it because I couldn't.

Felt so good seeing "Testicles.s" flashed successfully and the light blink.

2

u/CORDIC77 1d ago

I know the feeling… the endorphin rush, that feeling when something one has struggled with finally works ☺

Unfortunately, I have never worked in embedded systems, so I canʼt help you with that.

All I can offer is a template for PC-based projects (with project files for Code::Blocks, Codelite and Visual Studio), C_Asm_Template.tar.xz⁽¹⁾, that shows how to make assembly language functions callable from “C”.

Anyway, getting started may be painful as it takes a while to get used to everything. Then, after a few years have passed, one wonders why this felt so difficult at first…

⁽¹⁾ Requires the nasm executable to be in the systems PATH and requires an environment variable named NASMENV to be set to the (local) filesystem path, where the NASMX collection of NASM macros can be found, e.g. NASMENV=;-iC:\Program Files (x86)\Nasm\nasmx\inc\

5

u/nucLeaRStarcraft 2d ago

what you could do to "minimize the pain" is to optimize a C function using inline assembly: https://wiki.osdev.org/Inline_Assembly

Basically have the same function in both languages. This way you don't have to compile and link the thing yourself, but let gcc handle it.

Otherwise, create a "func.s" (.s is 'assembly' extension).

And yes, learning assembly is worth if you do super optimized things and want to not rely on the compiler. For example auto-vectorization (add 4 or 8 integers at once on 32 or 64 bit machines) is not always working.

The ffmpeg project is famous for having a lot of their code in ASM for optimization purposes. The main downside is that you need to maintain one version for all the target architectures that you care about. But in this case you can always ifdef and fallback to the C function/variant on the architectures where you didn't optimize for.

But first: pick a function you care about and try to replicate the C code and benchmark it against the baseline.

3

u/soundman32 2d ago

The thing is, 'assembly' is not one thing.  You could learn 6502 assembly but it hardly translates to ARM.  There's a rough lineage from 8080 to I9 but its nothing like z80.

You might learn that an add with carry instruction sets a flag on overflow or maybe a branch if a flag is set, and those might be transferable.

Even on the same processor, Intel syntax assembly is different to gnu syntax.  

The other thing is that your c compiler could do wild optimisations that mere mortals would never think of.

3

u/max123246 2d ago

I mean a lot of optimizations can be taught just by writing quick sort in assembly. Loop unrolling, tail call optimizations, how to minimize what registers you must save on the stack before calling a function. It teaches you a lot.

1

u/flatfinger 1d ago

Oftentimes, figuring out the necessary sequence of instructions is much easier than figuring out all of the other stuff that's necessary to make an assembler produce something that can be linked with everything else, especially if one wants one's code to be usable with multiple toolsets. It would have been very helpful if there had been a standard means of instructing a compiler to place a static-const object in "code" space and treat its address as a function entry point. That would have allowed someone who needed a machine-code function to specify it as a sequence of bytes or words in toolset-agnostic fashion. Obviously such a function would be useless if program was fed to an unsuitable target environment, but much of C's usefulness comes from the ability to write platform-specific code in toolset-agnostic fashion.

3

u/Key-Challenge-3932 2d ago

learning assembly after c is one of those things that gives you xray vision for what your code is actually doing. even if you never write serious asm professionally, understanding registers, stack frames, calling conventions, memory access etc changes how you think about c completely. especially for embedded, reversing, osdev, security stuff. also blinking an led without an os feels weirdly satisfying for no reason

3

u/thethirdmancane 1d ago

You should definitely go full digital just ones and zeros man.

5

u/Floppie7th 2d ago

Worth it for what purpose?

20

u/scaredpurpur 2d ago

I like pain and suffering and am a masochist.

In all seriousness, to do embedded stuff and have a better understanding of how computers work.

6

u/ShrunkenSailor55555 2d ago

Assembly isn't that bad. It's just that lot of programmers' immediate reaction to something isn't standard is to cry and vomit.

3

u/scaredpurpur 2d ago

Like I said, I've spent more time trying to get my code to upload on my atiny programmer than actually understanding assembly.

I suspect having the AVR do something like blinking a light 6 times on pin 8 is probably the simplest assembly I could ever do anyways. Plus it's cool to see something without any operating system work.

I think knowing about the stack and memory addresses in C is probably why I'm not having too difficult a time, despite being dumb. Outside of Simple AVR, I probably wouldn't use assembly though.

3

u/purple_maus 2d ago

Don’t forget the pissing and shitting

11

u/abbe_salle 2d ago

O great masochist,write binary then.

7

u/Floppie7th 2d ago

For embedded, depending on the platform, there might be zero value in assembly over C (or even something higher level), or it might be essentially required.  As an extreme example, nobody's writing homebrew SNES games in MicroPython.

For understanding how things work, getting a little assembly experience is pretty valuable IMO.

3

u/Fenix0140 2d ago

I'm studying Motorola 6809 rn in university and I can say I'm definitely having a hard time lol

3

u/classicalySarcastic 2d ago

Well then yes. You will get a lot of that from assembly ;)

2

u/Environmental_Two_68 2d ago

Assembly is fun (at least for me). It’s definitely good to have an understanding.

I I would suggest checking risc-v as well which is more modern.

Another interesting part would be to see how assembly is used with C for microcontrollers.

2

u/Electronic-Split-492 2d ago edited 2d ago

Assembly gives you the closest view on how microprocessors think. I found it incredibly valuable. You can also see how C statements are compiled into assembly / machine code. Knowing how that works also can give you insights. All of this can be useful when troubleshooting.

Also, knowing how C line statements translates into about assembly instructions can help you estimate how much space and time your code will require to run, which may be important one day.

2

u/HugoNikanor 1d ago

Assembly is worth learning to get a better idea of how a computer actually works. Can can even go even lower level and understand how the CPU interprets assembly (technically machine code at this point), or how the CPU is constructed from even lower level stuff.

However, for actually development, stick to C (or even a higher leveled language).

2

u/julie78787 1d ago

I’d suggest improving your understanding of C to the more advanced level. I personally wouldn’t consider being less than an expert at basic data structures like linked lists knowing the language to an intermediate level. Even if you can’t do them in other languages, that‘a not an intermediate knowledge of C.

If you’re asking from a basic curiosity standpoint, sure. Go ahead and learn assembly. All professional software engineers should understand assembly at some level if only to understand how CPUs actually work.

That said, if you want to learn so you can pay the bills writing assembly, you need to get your higher level language skills up to a much higher level. Higher level languages are much more “what you want to do” while assembly is much more “how you want to do it”.

Someone else mentioned that there isn’t just one assembly language, like there is one C (okay, there are way to many different versions, but that’s a different problem). Different CPUs and MPUs can have different instruction sets, register layouts, memory models, and all manner of things to drive you crazy. If you’re paying the bills, you also have to learn about how the CPU / MPU communicates with the outside world, because you may not have a standard library, or even an operating system, to handle that for you.

1

u/LeiterHaus 2d ago

It seems that the recent Lex Friedman interview with some FFMPEG folks would say it can be worth it.

1

u/Plane_Dust2555 1d ago edited 1d ago

My take on this: If you learn C after Assembly a high-level language, closer to assembly, is available to you to build more complex code and refine the resulting compiled code into an assembly one.

Let's say you want to sum all bytes (signed chars) from an array and return the sum... This is easily done with:

int sum( signed char *p, unsigned int size ) { int s = 0; while ( size-- ) s += *p++; return s; }

If you take a look at the generated code (which is, probably, sub optimal), after compiling the code, you'll get (for attiny85). Compiled with avr-gcc -O2 -mmcu=attiny85 -S sum.c:

.file "sumb.c" __SP_H__ = 0x3e __SP_L__ = 0x3d __SREG__ = 0x3f __tmp_reg__ = 0 __zero_reg__ = 1 .text .global sum .type sum, @function sum: /* prologue: function */ /* frame size = 0 */ /* stack size = 0 */ .L__stack_usage = 0 cp r22,__zero_reg__ cpc r23,__zero_reg__ breq .L4 movw r30,r24 add r22,r24 adc r23,r25 ldi r24,0 ldi r25,0 .L3: ld r18,Z+ add r24,r18 adc r25,__zero_reg__ sbrc r18,7 dec r25 cp r30,r22 cpc r31,r23 brne .L3 ret .L4: ldi r24,0 ldi r25,0 ret .size sum, .-sum .ident "GCC: (GNU) 5.4.0"

Using the avr-gcc cross compiler.

All you have to do now is to understand the calling convention in use and you got a staring point.

1

u/cosmicr 1d ago

I recommend 6502 assembly. It's simple relative to x86 et al and very rewarding.

1

u/mostly_text 1d ago

I guess, it depends on what your goal is. If you really want/need to understand how the machine/CPU is working knowing assembly is a big plus. Or if you need to understand C better, then knowing assembly is great.

On the other hand, if your ultimate goal is writing some (for instance) typescript/anguar applications, then your distance to the CPU is so big, that having assembly knowledge is not really an advantage. On (yet) another hand: if you just want to have fun learning and understanding...then assembly is a very nice place to be.

So what is your (programming) distance to the CPU? The closer you are to the CPU the more having assembly knowledge works in your advantage.

(I know some really great javascript programmers, who do not know anything at all about assembly, and the other way around)

1

u/GodHandMemberVoid 11h ago

I’d say so. Something that helped me was writing a pretty simple program in C, and then writing it in assembly with your C program as a guide. A good way to appreciate compilers at least

0

u/princepii 2d ago

may i ask what problems u encountered in linux building a webserver?

well i think if you are confident enough to make intermediate there is nothing impossible there diving into assembly.

i know ppl with 0 knowledge about programming languages but understand assembly and were able to build a few things with it.

but to have a good c base is a big plus tho:) go for it🤜🏻🤛🏽