# trying to understand the stack

Well hello there.

I am a relatively new in Assembly programming. I have an extensive background in C++ programming, but I haven't been coding in about four years. Now I've started coding once again and I decided to move closer to the machine and learn the Assembly language.

That's all for background. Now as for my problem. I am reading the book "Guide To Assembly Language Programming In Linux" (by Sivarama Dandamudi) and I'm at the moment learning how to use stack. Well, I came across a rather confusing error (, is it error or is it just me, I'm not completely sure) in the book. Here is the thing:

I page 243 there is a piece of code like this:

push number1
push number2
call sum

(yes, very basic procedure call routine)

a little later, in the same page, the author tells that:

"... Since the stack is a sequence of memory locations, ESP + 4 points to number2 and ESP + 6 points to number1. Note that both number1 and number2 are 16-bit values. For instance,

mov EBX, [ESP+4]

can be used to access number2 ..."

now, as for the problem... in page 244 there is a descriptive diagram of the stack, after the 'sum' procedure has been called, and after the previous EBP value has been pushed into the stack and the EBP has been set to point: move EBP, ESP

But the problem is, in the diagram it says that the position of number2 in the stack is EBP + 8, and the position of number1 is EBP + 12 , not EBP + 8 and EBP + 10 as it clearly should if number1 and number2 that were pushed in the stack were 16-bit values. (remember at first the book told - that is before the function call - that ESP+4 points to number2 and ESP+6 points to number1)

I just don't get it. Is it an error in the book or is it just me who doesn't understand it...

Well, as for the next problem I have with the way the stack has been explained in the book is this:

(going back to the paragraph in page 243
"... Since the stack is a sequence of memory locations, ESP + 4 points to number2 and ESP + 6 points to number1. Note that both number1 and number2 are 16-bit values. For instance,

mov EBX, [ESP+4]

can be used to access number2 ...")

if the number1 in the stack is 16-bit value, how on earth can we move number1 into EBX, a 32-bit register. Doesn't that completely mes up things, since how does the instruction mov EBX, [ESP+4] know that we are only reading the first 16 bits from the stack, and not the whole 32-bits, into EBX? Because clearly if we read 32-bits from the stack, wouldn't we then read both the number1 and number2 into the EBX register? I'm a bit confused as to how on earth we can use a 32-bit register to read a 16-bit value from the stack. Shouldn't we use "mov BX, [ESP+4]" instead?

I hope you understand the meaning of the problem that I'm trying to explain. I do understand that maybe my choice of words are not the best possible, but my excuse would be that english is not my first language. But in you understood my problem, I would really appreciate it if you could help me out with it. I know I'm still a very much beginner when it comes to Assembly, but I really want to learn the language, and I want to learn to understand how the computer works (and that includes learning to understand how the stack works). Thank you in advance.

• : "... Since the stack is a sequence of memory locations, ESP + 4
: points to number2 and ESP + 6 points to number1. Note that both
: number1 and number2 are 16-bit values. For instance,
:
: mov EBX, [ESP+4]
:
: can be used to access number2 ..."

This statement is incorrect. If the numbers are 16-bit values, they will not fit into the EBX register, which requires 32-bits. Also, whether the offset should be 2 or 4 depends on whether the CPU is in 16-bit or 32-bit mode. If in real mode or 16-bit protected mode, where procedure calls only use a 16-bit offset, the line should probably read:

MOV BX,[SP+2]

If in 32-bit protected or unreal mode, it should read:

MOV BX,[ESP+4]

Many programmers these days (at least the ones that work in Linux or Windows) get so used to working in 32-bit protected mode that they forget they can even work with 8-bit and 16-bit values.

It sounds to me like you're already understanding even more than you think you are.
• : : "... Since the stack is a sequence of memory locations, ESP + 4
: : points to number2 and ESP + 6 points to number1. Note that both
: : number1 and number2 are 16-bit values. For instance,
: :
: : mov EBX, [ESP+4]
: :
: : can be used to access number2 ..."
:
: This statement is incorrect. If the numbers are 16-bit values, they
: will not fit into the EBX register, which requires 32-bits. Also,
: whether the offset should be 2 or 4 depends on whether the CPU is in
: 16-bit or 32-bit mode. If in real mode or 16-bit protected mode,
: where procedure calls only use a 16-bit offset, the line should
:
: MOV BX,[SP+2]
:
: If in 32-bit protected or unreal mode, it should read:
:
: MOV BX,[ESP+4]
:
: Many programmers these days (at least the ones that work in Linux or
: Windows) get so used to working in 32-bit protected mode that they
: forget they can even work with 8-bit and 16-bit values.
:
: It sounds to me like you're already understanding even more than you
: think you are.

Thank you for your clarification. That explanation made some sense really. At first I thought that maybe I should just skip the whole part and just trust the author on it, but it just didn't feel quite right. Now I understand it a bit better... One question though arises now. What is a good environment to learn to program with 8- and 16-bit modes and could you give me a suggestion of some good books for that. I want to learn as much of Assembly language as possible, and so I think i shouldn't dismiss those modes completely.

Thank you once again
• The one I would probably recommend is "The Art of Assembly Language" by Randall Hyde. He's got an actual published book, and also PDF and HTML versions. Just Google "Art of Assembly" and you'll find it. Maybe somebody else has a better recommendation. I use books and "Ralf Brown's Interrupt List" mostly for reference on the BIOS and DOS calls, rather than for learning ASM.

I learned mostly by studying how other programs were written. My main source in the early days were the assembly language programs that were in PC Magazine. Unfortunately, those don't exist any more. This site (Programmers Heaven) has some example programs you can download, which might be helpful. I've got some source code on my web site as well (http://bretjohnson.us), but it's mostly for DOS TSR's. TSR's are quite a bit more complicated than "regular" programs are, so are usually not a good place for a beginner to start studying.

Hope that helps.