Setting up stack wrong (solved, no need to answer)

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
User avatar
pearmypie
Posts: 21
Joined: Sat Mar 01, 2025 8:06 pm
GitHub: https://github.com/ionutcatana

Setting up stack wrong (solved, no need to answer)

Post by pearmypie »

TL;DR: Someone helped me out. Be very mindful of GNU as and use `lea` instead of `mov` where appropriate.

The entire code is here: https://github.com/ciocolataculapte/risx-mirror
What am I doing wrong here? I am trying to push eax and ebx on the stack to use as arguments in my kernel main function. For testing purposes it does have a return statement. It returns 0x0BADCODE if eax didn't contain the multiboot2 magic number, and 0xDEADBEEF otherwise.

I've tries a couple variants to set up the stack in BSS, but I can't figure it out. My PC has 2 cores, so I'm trying to use the symbol "stack0" for my stack on the boot core. This was wrong, only "stack1" was valid.

Code: Select all


top:    .skip   0x10000                 # 64K stack
stack0: .skip   0x10000                 # stack for core 0
stack1:                                 # stack for core 1
Now I'm the code below, using "top0" as stack, but this doesn't work either.

Code: Select all

stack0:                                 # stack for core 0
top0:   .skip   STACK_SIZE
stack1:                                 # stack for core 1
top1:   .skip   STACK_SIZE
What am I doing wrong? Am I missing something in my assembly file, or is my linker script perhaps messing this up?
I am not doing anything in my multiboot 2 header, it's as minimal as it can be, maybe that's the issue.
Last edited by pearmypie on Fri Oct 24, 2025 7:49 am, edited 1 time in total.
User avatar
pearmypie
Posts: 21
Joined: Sat Mar 01, 2025 8:06 pm
GitHub: https://github.com/ionutcatana

Re: Setting up stack wrong

Post by pearmypie »

This works, my C code executes correctly. Can someone explain why my "stack0" is invalid?

Code: Select all

        .section .text
        .global _start
_start: mov     esp, stack1             # initialize stack
        mov     ebp, esp
        push    ebx                     # phys address of multiboot info struct
        push    eax                     # magic number
        (...)
        call    risx                    # should never return
        cli

Code: Select all

        .section .bss
        .align  16
bot0:   .skip   STACK_SIZE
stack0:                                 # stack for core 0 (broken)
bot1:   .skip   STACK_SIZE
stack1:                                 # stack for core 1 (good)
This is the solution:

Code: Select all

lea	esp, stack0
nullplan
Member
Member
Posts: 2034
Joined: Wed Aug 30, 2017 8:24 am

Re: Setting up stack wrong (solved, no need to answer)

Post by nullplan »

Truthfully, I am not very familiar with GNU as in intel mode. But I tested it, and it looks like even in that mode, you need to prefix $ to labels to get it to produce literals. So

Code: Select all

mov esp, $stack0
But the lea also works.
Carpe diem!
Octocontrabass
Member
Member
Posts: 6247
Joined: Mon Mar 25, 2013 7:01 pm

Re: Setting up stack wrong (solved, no need to answer)

Post by Octocontrabass »

pearmypie wrote: Fri Oct 24, 2025 6:06 amSomeone helped me out. Be very mindful of GNU as and use `lea` instead of `mov` where appropriate.
That works this time, but it's not exactly the right answer.

GAS uses Intel syntax, not NASM syntax. In Intel syntax, using a symbolic name as an operand tells the assembler to automatically select either an immediate operand or a memory operand depending on its type. You can override the automatic behavior by qualifying the name with square brackets if you want a memory operand, or the "offset" keyword if you want an immediate operand.

Code: Select all

mov eax, name        ; automatic
mov eax, [name]      ; memory operand
mov eax, offset name ; immediate operand
In this case, MOV with an immediate operand is equivalent to LEA with a memory operand, but you won't always have a convenient alternative instruction.
nullplan wrote: Fri Oct 24, 2025 8:49 amBut I tested it, and it looks like even in that mode, you need to prefix $ to labels to get it to produce literals.
This didn't work when I tried it. (Maybe because I specified ".intel_syntax noprefix"?)
nullplan
Member
Member
Posts: 2034
Joined: Wed Aug 30, 2017 8:24 am

Re: Setting up stack wrong (solved, no need to answer)

Post by nullplan »

Octocontrabass wrote: Fri Oct 24, 2025 9:46 am This didn't work when I tried it. (Maybe because I specified ".intel_syntax noprefix"?)
Yeah, I withdraw my earlier statement. I had misunderstood the objdump output. In reality, I created a reference on a symbol called "$stack0". But I can confirm the offset thing works.
Carpe diem!
User avatar
pearmypie
Posts: 21
Joined: Sat Mar 01, 2025 8:06 pm
GitHub: https://github.com/ionutcatana

Re: Setting up stack wrong (solved, no need to answer)

Post by pearmypie »

Yeah, either `lea esp, stack0` or `mov esp, offset stack0` works fine. I wish I didn't have to deal with this headache, but that's what I deserve for being a GNU shill & studying Intel syntax in university.
Post Reply