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.
so if you don't need any parameters, return values, or local vars, you can just use call and return?
If you also don't modify any of the callee saved registers specified by the ABI, yes.
Quote:
are all parameters and local vars accessed as offsets from %ebp in the main body of the function?
Usually, but if you prefer you can access them as offsets from esp instead.
If you follow the convention, ebp will point to the same spot in the stack frame through the entire body of the function.
esp typically changes during the execution of the function, so the offset from esp needed to access a parameter or local variable will be different at some place within the body of the function from some other place in the body of the same function. That can quckly lead to coding errors.
But if you find yourself short of general purpose registers (pretty common in 32 bit x86) you may find it worth the trouble to use ebp to hold some other pointer, while you access parameters and local variables using esp.
$ as asmtut.s -o asmtut.o
asmtut.s: Assembler messages:
asmtut.s:11: Error: suffix or operands invalid for `push'
asmtut.s:12: Error: suffix or operands invalid for `push'
asmtut.s:32: Error: suffix or operands invalid for `push'
asmtut.s:37: Error: too many memory references for `imul'
asmtut.s:39: Error: too many memory references for `cmp'
asmtut.s:47: Error: suffix or operands invalid for `pop'
That subl allocates a local 32 bit value at -4(%ebp) but it doesn't initialize that value to anything. Then you seem to be trying to use the value as if it had been initialized.
Once you understand what operations are best or only doable in registers, I expect you would eliminate the use of -4(%ebp) from your code and use a register instead.
But in later projects, you may need to use memory for local variables.
Whether you use memory or registers for local variables, you should remember to initialize your local variables, just as you know you need to in C.
Anyway, if you can't use some addressing modes for some operations, then how are you supposed to write good programs? In fact, my code is very similar to the power example in the book, and as shows errors on some parts that are the same!
Anyway, if you can't use some addressing modes for some operations, then how are you supposed to write good programs? In fact, my code is very similar to the power example in the book, and as shows errors on some parts that are the same!
You need to understand that assembler's purpose is not convinient programing. That is what high level languages are for.
Assembler is used to program as close as possible to the CPU's abilities.
You need to understand that assembler's purpose is not convinient programing. That is what high level languages are for.
Assembler is used to program as close as possible to the CPU's abilities.
I know that. I'm still just saying...
And where do I get this reference and how do I work around these limitations?
...
And where do I get this reference and how do I work around these limitations?
Every CPU manufacturer issues quite detailed documentation describing all the peculiarities.
You haven't yet looked, into, say, ARM . ARM is actually not bad - much more RISCy, so easier to understand. OTOH, it can be both big and little endian, and IIRC it has so called thumb mode (16 bits instead of 32 bits).
Every CPU manufacturer issues quite detailed documentation describing all the peculiarities.
You haven't yet looked, into, say, ARM . ARM is actually not bad - much more RISCy, so easier to understand. OTOH, it can be both big and little endian, and IIRC it has so called thumb mode (16 bits instead of 32 bits).
Maybe that's a good idea. Is there some sort of ARM emulator available? Perhaps even something that can run Linux?
And where do I get this reference and how do I work around these limitations?
Have a look at page 263 of the book. There is a reference table of some common x86 instructions. Depending on what chip you intend to prgram you might have to contact the chip manufacturer.
As for the work around:
Again, this are physical limitations we are talking about. High level languages 'hide' the chip's specific architecture.
If you are still wondering, why you can't do something like
Code:
imull -4(%ebp), 8(%ebp)
then keep in mind, that -4(%ebp) and 8(%ebp) point to just some memory locations. So it is just some circuits that are capable of holding some values. There is no cicuitry in your memory that can multiply this two dates. Only your CPU provides that functionality. So before you can operate on those values, your CPU has to fetch them first to its registers which have that special circuits to do a mutliplication and other logical operations.
where do I get this reference and how do I work around these limitations?
I looked on AMD's web site for a good directory of the documents you should get. I've seen that directory before, but couldn't find it.
I can still find all the individual documents. These are documentation for x86_64 CPUs. They cover both the 32 bit and 64 bit instruction sets, because the CPUs themselves include both. But some of the explanation is pretty skimpy for 32 bit specific sub topics, because that is not what they want you to use. You might need to find older documentation for more detail on 32 bit. (But I still think you should switch to 64 bit asm).
In fact, my code is very similar to the power example in the book, and as shows errors on some parts that are the same!
I figured out that part of your problem.
You already understood that the book was giving examples in 32 bit x86 asm and you know you have 64 bit Linux installed so the as command will default to 64 bit x86 asm. But you seem to have ignored that problem.
If you use as --32 instead of as it will assemble a program in 32 bit x86 asm.
The two asm languages have so much superficial similarity, that you got a trivial program written for 32 bit x86 asm to assemble and even run correctly in 64 bit x86 asm (even though each instruction did something subtly different). But you can't extend that to bigger projects. For example, 32 bit x86 asm has the pushl instruction to push a 32 bit value onto the stack. In 64 bit x86 asm, there is a lot more attention to stack alignment, so they intentionally prevented you from pushing 32 bits onto the stack. Regardless of the source size of the thing you want to push, it must be pushed onto the stack as 64 bits.
In memory references other than push/pop, the default integer size in x86_64 is still 32 bits, so there is no problem reading and writing 32 bit integers from/to memory, including from/to memory allocated on the stack and accessed through (%rsp) or (%rbp). You just can't push nor pop 32 bits.
So if you want to continue typing in 32 bit x86 asm examples, start assembling and linking them in 32 bit mode. (No special option is needed to run 32 bit in 64 bit Linux, just to assemble and link 32 bit).
I think you would learn more if you translated the examples to 64 bit x86 asm and assembled and linked the default way.
Distribution: M$ Windows / Debian / Ubuntu / DSL / many others
Posts: 2,339
Rep:
Quote:
I can still find all the individual documents. These are documentation for x86_64 CPUs. They cover both the 32 bit and 64 bit instruction sets, because the CPUs themselves include both. But some of the explanation is pretty skimpy for 32 bit specific sub topics, because that is not what they want you to use. You might need to find older documentation for more detail on 32 bit. (But I still think you should switch to 64 bit asm).
Does 64 bit ASM work on a 32bit OS working on a 64 bit processor?
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.