How to Call Assembly Code from C

แชร์
ฝัง
  • เผยแพร่เมื่อ 1 ธ.ค. 2024

ความคิดเห็น • 119

  • @szigo3211
    @szigo3211 6 หลายเดือนก่อน +254

    Okay, now I can add "assembly expert" to my CV

    • @leonelh264
      @leonelh264 6 หลายเดือนก่อน +1

      Hell yeah

  • @MadMathMike
    @MadMathMike 6 หลายเดือนก่อน +108

    It's crazy how well you can demystify some things with the simple examples. Makes this stuff feel so much more accessible!

    • @xCwieCHRISx
      @xCwieCHRISx หลายเดือนก่อน

      @@MadMathMike now you are ready to program Roller Coaster Tycoon

  • @pavfrang
    @pavfrang 6 หลายเดือนก่อน +21

    The fact that you are showing documentation for every single step is unprecedented! Thank you for the content once more!

  • @ujin981
    @ujin981 6 หลายเดือนก่อน +27

    this should be the golden standard for howto's

    • @whamer100
      @whamer100 6 หลายเดือนก่อน +3

      we need a standard above golden honestly, the style of howto nir does goes above and beyond my expectations every time, we need a diamond standard

  • @Yougottacryforthis
    @Yougottacryforthis 6 หลายเดือนก่อน +57

    thought you were going for the inline assembly

  • @space9824
    @space9824 5 หลายเดือนก่อน +2

    I have no idea why, but I love that this is possible.

  • @bmx666bmx666
    @bmx666bmx666 6 หลายเดือนก่อน +9

    At university 20 years ago, I had a project involving MD5 hash calculation written in Delphi/Pascal. For some reason, the Pascal implementation was incredibly slow, even with bitwise optimization. I injected ASM into my project to speed it up, and even the simple, unoptimized ASM version was twice as fast as the optimized Pascal version. With some additional tweaks, I improved performance by up to three times. Nowadays, compilers are smart enough 😅

  • @comoyun
    @comoyun 6 หลายเดือนก่อน +10

    It's great to see some updates from this channel :)

  • @PremiereStoss-qm9un
    @PremiereStoss-qm9un 6 หลายเดือนก่อน +5

    Awesome video! More assembly/C. Either together or separate. Great job!

  • @JohnUrbanic-m3q
    @JohnUrbanic-m3q 6 หลายเดือนก่อน

    I knew this, but I was curious to see how well you would cover this in the advertised 4 minutes. The answer is "very well". Very well indeed.

  • @PauloConstantino167
    @PauloConstantino167 5 หลายเดือนก่อน

    Hi there. I love your videos. Such beautiful simplicity.

  • @DimDima09
    @DimDima09 6 หลายเดือนก่อน +1

    These videos are so cool and easy-to-understand :) Well done!

  • @mcmaddie
    @mcmaddie 6 หลายเดือนก่อน +1

    Ah, brings back memories from early 90's. Actually back then I inlined asm in C too not just external files.

  • @simonepernice8059
    @simonepernice8059 6 หลายเดือนก่อน

    Thank you very much, I have always wondered how to call assembler code, your explanation is great!!! Thank you so much!! It

  • @whamer100
    @whamer100 6 หลายเดือนก่อน

    this is one of the more obvious tricks id say, but it's still a really cool thing you can do. and as always, you make it so easily digestible

  • @AlucTheMia
    @AlucTheMia 6 หลายเดือนก่อน +1

    Great video, super underrated channel!

  • @kinershah464
    @kinershah464 6 หลายเดือนก่อน +1

    Nice video. That calling convention was new for me. Please also make a video on how to create functions in assembly with more complex data types.

  • @Jonathan-ru9zl
    @Jonathan-ru9zl 5 หลายเดือนก่อน

    You make hard things easy 🙌🙏

  • @scottfranco1962
    @scottfranco1962 5 หลายเดือนก่อน

    The biggest hint for assembly calls is to use -S on gcc and generate a prototype for your function in assembly. IE, if you want to make an assembly function to be called int addnumbers(int a, int b) { return a+b; } IE, do a prototype of the function in C, then use gcc -S to generate the file. Then you just edit the output file .s to add your assembly code. gcc fills in all the details for you.
    This does generate AT&T format code, not Intel code, but I think you are better off learning the AT&T code format in any case. Its not that different, and you can use gcc to generate example code for you.

  • @shr1mpy27
    @shr1mpy27 6 หลายเดือนก่อน +3

    Great content as usual ❤

  • @justinnamilee
    @justinnamilee 6 หลายเดือนก่อน +4

    I'm coming in for another, "Neat!"
    Neat!

  • @martinstu8400
    @martinstu8400 6 หลายเดือนก่อน +2

    Hi assembly experts, can you explain why he passes and returns values in R registers, which are 64 bits, but in C he specified int, which is 32 bits. Why is there no conflict?

    • @user-oe4id9eu4v
      @user-oe4id9eu4v 6 หลายเดือนก่อน +2

      There is conflict, but conveniently E registers are just lower 32 bits of R registers. So as consequence meaninglessly higher portion of %rax and %rdi will be modified, but that's fine.

  • @KimGameDev
    @KimGameDev 6 หลายเดือนก่อน +2

    This is actually brilliant, you could use this method to create a new language via assembly linked into C. Makes me wonder how the o-file-format looks like to create a compiler for the new language so that you go directly into generating those o-files using that compiler. Once more you have dropped a golden nugget 👍👍

    • @Ba-gb4br
      @Ba-gb4br 6 หลายเดือนก่อน +2

      The .o files or object files contain machinecode of the compiled source files without concrete adress values for extern stuff like calls to functions, which are not defined in the same source file. The linker takes these .o files and resolves the adresses to the concrete ones used in the final executable file.

    • @soyitiel
      @soyitiel 6 หลายเดือนก่อน

      I'm almost certain sure that's how Zig does it

  • @userjm-my9hn
    @userjm-my9hn 6 หลายเดือนก่อน

    thank you so much for your content and videos, it seems like there are not many people who teach or share about actually putting C to practical use from what i've found but your videos fill so many gaps and are so helpful, thank you again and if you are open to take any suggestions for new videos in C, maybe how to parse JSON / XML or making HTTP requests for beginners in C?

  • @ismbks
    @ismbks 6 หลายเดือนก่อน +2

    does assembly use the following syntax? instruction dest, src
    also are registers special variables? common for all assembly? like you used rax?

    • @computerbutter8124
      @computerbutter8124 6 หลายเดือนก่อน +2

      kinda, yeah.
      with assembly, things differ in that each symbol is working almost with bare metal components, so it’s best if you get a good understanding of how computers work at their bare lowest functions. most good youtube assembly tutorials should cover this kinda thing at the start before you even get to assembly.

    • @Masterix.
      @Masterix. 6 หลายเดือนก่อน

      If you mean x86 assembly then yes and yes.
      Syntax will be different between different architectures (x86, arm, risc-v...)

    • @zun1777
      @zun1777 6 หลายเดือนก่อน +2

      intel syntax uses dest, src
      atnt does it the other way around

    • @ismbks
      @ismbks 6 หลายเดือนก่อน

      thanks guys!

  • @TheRailroad99
    @TheRailroad99 6 หลายเดือนก่อน +1

    I usually declare the functions with the extern keyword if added into a C file like this.
    That way it's extra obvious they are from a different file.
    Or I create a header file.

    • @RayBellis
      @RayBellis 6 หลายเดือนก่อน +1

      I was wondering about this, but apparently `extern` is the default linkage for a C function declaration.

    • @TheRailroad99
      @TheRailroad99 6 หลายเดือนก่อน +1

      @@RayBellis yes, it is. Still better for readability though

  • @richardericlope3341
    @richardericlope3341 6 หลายเดือนก่อน

    Should have told me this 20 years ago. I had to fetch arguments from stack then add to SP(for speed) the size of the args plus return address. Were naked functions supported back then?
    I remember GCC supporting inline asm with the .intel directive though as this was my fallback until optimizing compilers came into the picture.

    • @D0Samp
      @D0Samp 6 หลายเดือนก่อน

      There is the fastcall convention that can pass two 32-bit arguments in ECX and EDX (vectorcall also allows floats and vector types in SSE/AVX registers). For lack of general registers on IA-32, you usually can't pass more. Also only Visual C++ and GCC 4.0 onwards supported it.

  • @JackieJKENVtuber
    @JackieJKENVtuber 6 หลายเดือนก่อน +1

    Oh hey, it's the shower thought i immediately forgot about!

  • @hwstar9416
    @hwstar9416 6 หลายเดือนก่อน +2

    why would execstack be relevant here? I thought that only mattered with nested functions

  • @marouaniAymen
    @marouaniAymen 6 หลายเดือนก่อน

    Thanks for the video, but what if I want to build a secure executable ? I mean, I don't want to have the '-z noexecstack' option during my build ? it seems like calling assembly from C is not secure.

    • @nirlichtman
      @nirlichtman  6 หลายเดือนก่อน +2

      The -z noexecstack option does not make the executable unsecure, its just to tell gcc that the stack should be non-executable, otherwise there would be a warning when combining the assembly and the c code with GCC. there is also a way to specify that the stack is non executable inside of the assembly and that can be an alternative for the flag

    • @marouaniAymen
      @marouaniAymen 6 หลายเดือนก่อน

      @@nirlichtman Thanks for the clarification

  • @andreffrosa
    @andreffrosa 6 หลายเดือนก่อน +1

    Can you make a video about making coroutines/virtual threads in C and assembly?

  • @not_kode_kun
    @not_kode_kun 3 หลายเดือนก่อน

    Hi Nir! I've been following your videos for a good while, you're one of my favorite content creators ever. So much golden information on here. I've fallen in love with low-level coding (C, os-dev, embedded, etc) in the past 2 years and I'd love to pursue it as a career path.
    I tried getting a formal education in programming before but I just can't bear working with Java and web stuff, i find it incredibly boring and soulless.
    Do you have any tips on how to get into the market in this area (low-level programming)? is it even a viable path or is it just a pipe dream in 2024? whenever i find jobs for C developers or anything in that nature, they're only looking for senior devs with years and years of experience and a bachelor's.
    Thanks for the amazing video as always!

  • @katiagalkina4607
    @katiagalkina4607 6 หลายเดือนก่อน

    man! I had no idea of those directives! made my day! ty. btw, is it a signed addition?

    • @nirlichtman
      @nirlichtman  6 หลายเดือนก่อน +1

      It is both a signed and unsigned addition, in the end in terms of the actual bytes in memory signed and unsigned are the same, but the ADD instruction takes care of setting the sign flag properly after the addition, more info in the official intel instruction reference :) www.intel.com/content/www/us/en/developer/articles/technical/intel-sdm.html

    • @katiagalkina4607
      @katiagalkina4607 6 หลายเดือนก่อน

      Tysm for the feedback and the link. 😊 rax indeed truncates to eax (from the objdump). so are rdi and rsi before calling. thus adding __INT_MAX__ and -__INT_MAX__-1 gives -1 although 64bit registers are used. and addNumbers(5 , -1) gives 4.

  • @Turing-t2e
    @Turing-t2e 6 หลายเดือนก่อน

    Thank you for the explanation

  • @FastKonrad
    @FastKonrad 6 หลายเดือนก่อน +2

    fun fact: compilers often uses load effective address instead of add instruction:
    addNumbers:
    lea eax, [rdi+rsi]
    ret

  • @TR3A
    @TR3A 6 หลายเดือนก่อน +2

    I’m just missing how the arguments got passed to the registers RDI and RSI.

    • @dorquemadagaming3938
      @dorquemadagaming3938 6 หลายเดือนก่อน +1

      It's defined by the function calling convention. Linux and pretty much every UNIX-like OSes on the x86-64 platform use the System V AMD64 ABI, where registers RDI, RSI, RDX, RCX, R8 and R9 are used to pass the first 6 integer arguments to a function.

    • @typedef_
      @typedef_ 6 หลายเดือนก่อน +2

      it's the call convention of gcc. Before the actual subroutine call, gcc will add "mov" instructions to take the C function arguments and put them in those registers

    • @TR3A
      @TR3A 6 หลายเดือนก่อน +1

      @@typedef_ Thank-you!

    • @TR3A
      @TR3A 6 หลายเดือนก่อน

      @@dorquemadagaming3938 Thank-you!

  • @nezby3945
    @nezby3945 6 หลายเดือนก่อน

    Wow this was really cool I know about CDECL and STDCALL conventions from school but that’s for x86_32 nasm. Why don’t you have to push the arguments onto the stack and why do you just use registers? Is it faster that way? Can’t there be something useful in RDI that you’ve overwritten?

    • @nirlichtman
      @nirlichtman  6 หลายเดือนก่อน

      Unlike most popular x86 calling conventions which pass all the arguments through the stack, on x64 the calling conventions pass the first couple of arguments through registers and the rest through the stack.

    • @nezby3945
      @nezby3945 6 หลายเดือนก่อน

      @@nirlichtman okay and you don’t need to create a new stack frame, save and load the previous states of registers when using this convention? Something along the lines of pushad popad, so that the value 5 as from your example doesn’t change in the rdi register when calling the function? Or is it because C handles that on its own?

    • @nirlichtman
      @nirlichtman  6 หลายเดือนก่อน

      @@nezby3945 in this case since these registers are used for passing args (and rax is used for the ret value), no preservation is needed

    • @D0Samp
      @D0Samp 6 หลายเดือนก่อน +1

      ​@@nezby3945 In leaf functions like these that don't use the stack, you don't have to set up a stack frame. Even if you do, the SysV ABI defines a "red zone" of 128 bytes under the stack pointer that you can use without interference from signal handlers. Also since RDI is one of the registers used to pass parameters, it's also part of the scratch registers that the caller has to save if needed before the function call, while the called function can use it freely.

    • @nezby3945
      @nezby3945 6 หลายเดือนก่อน

      @@D0Samp Oh wow I had no idea that It worked like that our uni teacher never told us something of such existed. Thank you very much for clarifying and taking the time out of your day to do so. If only there were more people like you :D!!!!!!!

  • @felipecolona5486
    @felipecolona5486 6 หลายเดือนก่อน

    your videos are awesome!!

  • @insert0name0here91
    @insert0name0here91 4 หลายเดือนก่อน

    How did you get the linux terminal on powershell?

    • @plato4ek
      @plato4ek 4 หลายเดือนก่อน

      it's WSL2

  • @1495978707
    @1495978707 6 หลายเดือนก่อน

    3:32 Pretty sure newer versions of GCC automatically disable executable stack except when there's nested functions

  • @roz1
    @roz1 6 หลายเดือนก่อน

    Hi @NirLichtman this is just library linking.... It's not calling assembly from c. Even if you have wrote the same code in c and compiled it and linked the binary it would have worked. But anyways good video.

  • @andies1
    @andies1 6 หลายเดือนก่อน

    i thought this would be a video about inline assembly in c, i'd like to see how it works

  • @mzakyr342
    @mzakyr342 6 หลายเดือนก่อน

    just asking, which one is more better? intel or AT&T syntax?

    • @nirlichtman
      @nirlichtman  6 หลายเดือนก่อน

      In the end, it depends on which one you feel more comfortable with/the project you are working on, for example the assembly parts in the Linux kernel are written with the AT&T syntax, but the general standard syntax of x86 assembly is in the intel syntax (including in the official intel manual), I would recommend being at least familiar in a basic level with both.

    • @D0Samp
      @D0Samp 6 หลายเดือนก่อน

      The only purpose of AT&T syntax is uniformity among instruction sets for compiler output. Its (source, destination) format comes from the DEC assembler for the PDP-11 and VAX (and Alpha), which was the birth place of Unix. Basically all other modern instruction sets like MIPS, ARM and RISC-V use (destination, source) without prefixes as well.

  • @AS-oz6ep
    @AS-oz6ep 6 หลายเดือนก่อน

    Tried going the other way around (calling c from assembly) back in the day for a school project.. could never figure out how to do it properly.

    • @nirlichtman
      @nirlichtman  6 หลายเดือนก่อน

      That's a good idea for a future vid, added to my list

  • @cuachristine
    @cuachristine 6 หลายเดือนก่อน

    Is it possible to call assembly code from higher level languages, like C# or Java?

    • @nirlichtman
      @nirlichtman  6 หลายเดือนก่อน +1

      Yes, but in most cases not directly like we can do with lower level languages such as C, for example in Python you need to create a separate DLL or Shared Object (depending if you are writing for Windows or Linux) which implements a specific interface that Python can work with, so that Python can later import it and work with it

  • @Wagner-uv6yp
    @Wagner-uv6yp 6 หลายเดือนก่อน

    Stupid question but where do I even start with all this computer stuff if I don't even understand what I'm looking at?

    • @nirlichtman
      @nirlichtman  6 หลายเดือนก่อน +1

      I started programming by learning some HTML in w3schools and building websites since I really wanted my own website, from there on went and learned more advanced stuff first CSS and JavaScript and eventually also C and Assembly, I would recommend starting with the basics first and only after you start feeling comfortable moving on to more advanced stuff, good luck!

    • @Wagner-uv6yp
      @Wagner-uv6yp 6 หลายเดือนก่อน

      @@nirlichtman thanks bro

    • @Wagner-uv6yp
      @Wagner-uv6yp 6 หลายเดือนก่อน

      @@nirlichtman I got another question. What resources do you recommend for learning command line and general computer knowledge stuff like how to work operating systems and shit?

    • @nirlichtman
      @nirlichtman  6 หลายเดือนก่อน

      Depends, are you interested in learning Windows or Linux? If you mean Linux, in general I would highly recommend learning to work with man pages and using them to learn about the various basic commands, you can start by running "man man", and then start by reading the man pages of the basic commands for instance ls, cat, grep ... For getting started videos about this kind of stuff I would recommend Network Chuck and Engineer Man

    • @Wagner-uv6yp
      @Wagner-uv6yp 6 หลายเดือนก่อน

      @@nirlichtman More so on Windows but Linux is interesting too. I'm a total beginner so I wanted to learn Windows first. Ty for the youtuber recommendations though.

  • @its-CartoonMirror
    @its-CartoonMirror 6 หลายเดือนก่อน

    thanks man :)
    just realised the linker finds similar functions names in the given file name ( as parameters )

    • @midnightfuture
      @midnightfuture 6 หลายเดือนก่อน

      *Symbols*. The linker finds one and only one matching symbol definition for each reference, in static linking literally copying the definition code into place and in dynamic linking inserting an executable address resolution.
      The distinction is important when you have function overloads, name mangling (functions in classes, in C++, for example), and non-function objects. Calling convention also sometimes impacts the fully qualified symbol name, and therefore resolution.

  • @sergeiborodin9254
    @sergeiborodin9254 6 หลายเดือนก่อน

    Can you please make a video about __asm embedding right into C/C++ source code?

    • @nirlichtman
      @nirlichtman  6 หลายเดือนก่อน +1

      Yah thats a good idea, I will add to my list

    • @sergeiborodin9254
      @sergeiborodin9254 6 หลายเดือนก่อน

      @@nirlichtman Thank you!

  • @techleef-tn
    @techleef-tn 6 หลายเดือนก่อน

    Is this actually "calling assembly code from C" ?, the compiler will generate main.s and then the assembler will assemble it to main.o, since you have ext.o, the linker will know that there is an UND symbol in main.o and it will statically link it from ext.o, this is not calling Assmbly from C, so I think writing Assembly in a C file or including an assembly file from C file is the actual thing you need to cover. BTW, good videos, I really appreciate your work.

    • @D0Samp
      @D0Samp 6 หลายเดือนก่อน +1

      From the linker's perspective there's indeed no programming languages at all, it resolves symbols and takes startup code (from the C standard library, if you use the C compiler frontend) to produce an executable. The biggest difference here is that only the foreign function follows the conventions of the C compiler, usually it's either a higher level language like C++ or Rust that calls into a C library or two of them using C conventions as a lingua franca to communicate. I think it's still valid to call this "calling assembly" if that assembly procedure just follows the common denominator in calling conventions.

  • @NovabitsYT
    @NovabitsYT 6 หลายเดือนก่อน

    You didn't say the outro line! But great vid as always

  • @AlucTheMia
    @AlucTheMia 6 หลายเดือนก่อน

    Right in the part where you said that C needed to know that the addNumbers function existed, shouldn't you have used "extern int addNumers(...);"? Great video by the way, cheers!

    • @nirlichtman
      @nirlichtman  6 หลายเดือนก่อน

      Thanks! Regular non-inline function declarations are extern by default, so no need

    • @xd_metrix
      @xd_metrix 6 หลายเดือนก่อน

      All functions in C are implicitly extern

  • @KevinInPhoenix
    @KevinInPhoenix 5 หลายเดือนก่อน

    C is already a "portable assembly language" so calling assembly language from C is a bit redundant.

  • @roz1
    @roz1 6 หลายเดือนก่อน

    Hi @NirLitchman you promised that you would make a sereis on linux from boot to shutdown... i.e Indepth linux kernel walkthrough.... Eagerly waiting for that.

    • @nirlichtman
      @nirlichtman  6 หลายเดือนก่อน +1

      Stay tuned for next video :)

  • @cainagnascimento
    @cainagnascimento 6 หลายเดือนก่อน

    I dindt expect to see Windows on a C and Assembly video

  • @c.e.o.9985
    @c.e.o.9985 6 หลายเดือนก่อน +1

    This is called efficient code

  • @unixbhaskar
    @unixbhaskar 6 หลายเดือนก่อน

    Thanks.

  • @ahmedatwa3761
    @ahmedatwa3761 6 หลายเดือนก่อน

    Next video calling C functions from Java

  • @guilherme5094
    @guilherme5094 6 หลายเดือนก่อน

    👍Thanks man!

  • @pandaDotDragon
    @pandaDotDragon 6 หลายเดือนก่อน

    nice
    (5+5 is probably not the best test to check this code 😉)

  • @mikehu404
    @mikehu404 6 หลายเดือนก่อน

    This is very hardcore!

  • @Agesilas2
    @Agesilas2 6 หลายเดือนก่อน +3

    well, that dead short and simple one could have been implemented with inline asm, and asm/C interactions deserve a slightly longer video

    • @JeersNX
      @JeersNX 6 หลายเดือนก่อน +2

      shut up, he did what the title said.

    • @Agesilas2
      @Agesilas2 6 หลายเดือนก่อน +1

      @@JeersNX no u

    • @typedef_
      @typedef_ 6 หลายเดือนก่อน

      tHiS cOulD hAvE beEn 🤡

  • @MarianoBustos-i1f
    @MarianoBustos-i1f 6 หลายเดือนก่อน

    Your code is beautiful, your desktop cries for some ricing, my brother in Christ.

  • @hoteny
    @hoteny 6 หลายเดือนก่อน +1

    hi

  • @daboi1675
    @daboi1675 6 หลายเดือนก่อน

    Low Level Programming, fuck yea.

  • @xfaon
    @xfaon 6 หลายเดือนก่อน

    Why would anyone do this anyway? Isnt it dangerous as the c++ code may also be messing with registers and us doing the same may mess up state?

    • @RayBellis
      @RayBellis 6 หลายเดือนก่อน +1

      The EABI guarantees that the specified input registers do not need to be preserved. If you interfere with other registers you have to save and restore their state.

    • @xfaon
      @xfaon 6 หลายเดือนก่อน

      @@RayBellis Oh I see, tiny context switch

  • @Hello-jh1rq
    @Hello-jh1rq 6 หลายเดือนก่อน +1

    hi