Ema Dovnisher
Ema Dovnisher

Reputation: 11

What happens to the Stack and the sp when we write the PUSH command? (Assembly)

I just started learning Assembly and my friend and I got different ideas about what exactly happens in the following command:

Push 1234h

Our problem is: where will the first digits (12) will go to in the stack ?
ss:[sp-2] ?
ss:[sp-4] ?

*sp =stack pointer

Upvotes: 0

Views: 672

Answers (3)

Drew McGowen
Drew McGowen

Reputation: 11706

Assuming you're talking about x86 hardware (since you specify the sp register), the bytes will be pushed highest-order (most significant) to lowest-order (least significant). In this case, it'll push the byte 12h, followed by the byte 34h. Since the x86 stack pointer decreases when you push items, the memory layout would look like this:

[sp+1] = 12h
[sp]   = 34h

If you access [sp] as a word (two bytes), you'll get your original value:

[sp] = 1234h

Upvotes: 3

user35443
user35443

Reputation: 6403

In real mode (it looks like you're trying to make programs for it), address is calculated first. The formula is pretty simple:

address = (segment<<4)+offset

Then this address is substracted by size of element you're trying to push (word: 2 bytes, dword: 4 bytes, qword: 8 bytes). Third step is writing data on resulting position. Therefore if SS is 0x30 and SP 0xFF, then:

  1. address = (0x30<<4)+0xFF = 0x3FF
  2. Element is word, so we substract 2: position = 0x3FF - 2 = 0x3FD
  3. Writing data on resulting position (as C pointers): *(unsigned char*)position = LOBYTE(0x1234), *((unsigned char*)position+1) = HIBYTE(0x1234).

So, byte SS:[SP] = 0x34 and byte SS:[SP+1] = 0x12. Note that stack grows/expands down, so there won't be SP-x, but SP+x.

In protected mode, things are bit more complicated (I'll write here only process of working with segment register):

  1. First, processor get's address of Global Descriptor Table Descriptor (which is loaded by LGDT instruction).

  2. Processor compares value of segment register with size of GDT (if it's greater, exception is thrown). It also checks if segment register isn't pointing to null descriptor (SS!=0)

  3. Then processor gets pointer to GDT entries, and calculates offset from start of GDT (using SS*8).
  4. Processor must check some things:

    4.1. Is segment present? 4.2. Do we have enough priviliges to access segment? 4.3. Is it code segment? 4.4. Is it writable? 4.5. Is ESP*granularity+base < limit 4.6. Is it system segment?

  5. Then it calculates address by base_of_segment+ESP.

  6. After it it continues similary to real mode.

Upvotes: 0

SomeWittyUsername
SomeWittyUsername

Reputation: 18338

Believe it or not but both of you can be right. The bytes ordering depends on the endianness of your machine.

Upvotes: 0

Related Questions