ProgrammingThis forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
I was reading through the examples and got confused -- aren't you supposed to push function parameters onto the stack, not save them in registers?
You can use the registers as well. Often times I don't use push or pop with simple calls at all, because the registers already hold all the information that is needed in a call.
Though, I think I'm not the best to help you because I've been learning to write pure assembly, so I haven't read much on utilizing it with C or any other programming language as of yet. As well as I only program in 32bit at the moment and only using the intel manuals which you don't need.
The very first thing you need to do is to make certain that you have the right programming tools at hand. You can either write your first program with a debugger or else with an assembler and linker.
One debugger tool is called DEBUG.EXE and it is from Microsoft. It is sometimes installed from the CD-ROM onto the hard disk when the operating system is first placed there. But not always. (It is on the CD-ROM, but not always copied to the hard disk.) Another possible debugger is a 16-bit capable debugger like GRDB from David Lindauer. While Microsoft traditionally includes DEBUG on most operating systems it makes, it isn't always installed. If you cannot find it on your machine, consider using GRDB from David's site (see my PC Tools web page, near the bottom of the page.)
For more general purpose assembly programming, you will need an assembler and linker. ML is an assembler from Microsoft and LINK is the linker, also from Microsoft. They are also pointed at by my PC Tools web page. I'd recommend getting all of these you can and installing them. That way you can try out various ways of writing your programs.
Be sure that you update your PATH variable so that these programs are accessible from the command line or else put them all into a common directory where you will be working and just create your programs there.
The very first thing you need to do is to make certain that you have the right programming tools at hand. You can either write your first program with a debugger or else with an assembler and linker.
One debugger tool is called DEBUG.EXE and it is from Microsoft. It is sometimes installed from the CD-ROM onto the hard disk when the operating system is first placed there. But not always. (It is on the CD-ROM, but not always copied to the hard disk.) Another possible debugger is a 16-bit capable debugger like GRDB from David Lindauer. While Microsoft traditionally includes DEBUG on most operating systems it makes, it isn't always installed. If you cannot find it on your machine, consider using GRDB from David's site (see my PC Tools web page, near the bottom of the page.)
For more general purpose assembly programming, you will need an assembler and linker. ML is an assembler from Microsoft and LINK is the linker, also from Microsoft. They are also pointed at by my PC Tools web page. I'd recommend getting all of these you can and installing them. That way you can try out various ways of writing your programs.
Be sure that you update your PATH variable so that these programs are accessible from the command line or else put them all into a common directory where you will be working and just create your programs there.
I do not have ANY Microsoft products on my computer (including Windows), I don't want any, and they won't run on Linux.
I really don't understand why you are pushing M$ products on me. Could you have at least done some research?
I already have all the programming tools I need thanks to the GNU project ("gcc" C compiler, "g++" C++ compiler, "gdb" debugger "ld" linker, "as" assembler).
Also, is it possible to just embed asm code into a C source file?
Yes, but it is much harder than you would expect. There is a very complicated counter intuitive syntax for telling the compiler the inputs, outputs and clobbers of a block of asm code.
I know that method of asm coding and recently I've used it more than other methods, but I strongly recommend against it for anyone just learning asm.
Once you know asm, if you decide to use it in serious work, you might need to learn the syntax for embedding asm in C.
The method Smeezekitty showed you (skipping the whole syntax for coordinating your register use with the compiler's register use) is unsound.
Quote:
Originally Posted by MTK358
I was reading through the examples and got confused -- aren't you supposed to push function parameters onto the stack, not save them in registers?
In many architectures, the ABI specifies that all parameters are pushed onto the stack.
But in x86_64, the ABI specifies some parameters are passed in registers (which typically makes much more efficient code). If you have more parameters, the rest would be passed on the stack.
Quote:
Originally Posted by Mol_Bolom
You can use the registers as well. Often times I don't use push or pop with simple calls at all, because the registers already hold all the information that is needed in a call.
When you write an asm function to be called only by other asm functions, you can pass parameters however you like (you can ignore the ABI). So even in 32 bit x86 (where parameters are passed on the stack by functions obeying the ABI) it is common to use registers, because that is more efficient when you can ignore the ABI.
If your asm code is called by C code or if it calls C code or calls standard library functions, all those calls must obey the ABI. You don't get to choose whether parameters go on the stack or in which registers. The ABI specifies that.
Even for asm functions called only by asm, obeying the C ABI may be a good idea, especially in x86_64 where it is a pretty efficient ABI.
You can use the registers as well. Often times I don't use push or pop with simple calls at all, because the registers already hold all the information that is needed in a call.
Though, I think I'm not the best to help you because I've been learning to write pure assembly, so I haven't read much on utilizing it with C or any other programming language as of yet. As well as I only program in 32bit at the moment and only using the intel manuals which you don't need.
How does the function know whether the parameters are in the registers or on the stack?
EDIT: One other thing that puzzles me is whether the main() function in C code is actually turned into a function in Assembler, or is it not really a "function"?
How does the function know whether the parameters are in the registers or on the stack?
Same way it know the sequence, meaning, types etc. of its parameters in a normal function (that obeys the ABI):
The author of the functions decides on the number of parameters and the types and sequence and meaning etc.
In a high level language, a lot of that info is specified by the function declaration. But there is usually still some that must be specified by comments or other documentation.
The author of a call to a function should read the comments and/or documentation to find out how to call the function.
In asm, less is specified by declarations, so more must be specified by comments and documentation.
If a function doesn't obey the ABI, a whole lot of details of its interface must be specified by comments or documentation, so it will be possible to write correct calls to that function.
Quote:
EDIT: One other thing that puzzles me is whether the main() function in C code is actually turned into a function in Assembler, or is it not really a "function"?
main() in C code is compiled as an ordinary function, obeying the ABI the same way other functions do.
main() is not the starting point of a program. The starting point is usually some asm code that gcc tells the linker to link in. That code does various initialization, then calls the function main(). If main() returns, that startup code preserves the return code from main and calls some version of exit() (which is also a function, but doesn't return).
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.