1

I am learning x86 assembly using Nasm on Linux(Debian 12). I already know what is stack, so I thought when we code in assembly, we implement it ourselves. But I saw instructions like push and pop which are meant for operations on stack. So is there a stack already implemented and ready to use? if yes, then how is it used and how can we use it. I created a strlen function in asm

section .data
hello db "Hello World!",10,0

section .text
global _start

_start:
    mov rax,hello
    call strlen
    mov rax,1
    mov rdi,1
    mov rsi,hello
    syscall
    mov rax,60
    mov rdi,0
    syscall

strlen:
    mov rdx,0

strlen_loop:
    cmp byte[rax],0
    jz strlen_finished
    inc rdx
    inc rax
    jmp strlen_loop
strlen_finished:
    ret

This calculates the length of the string and prints it. I could use push rax to put the value of the rax onto the stack so that the value which was already in rax doesn't get lost. So we only use this already implemented stack this way or does the processor also uses this stack in some other ways? And what is the difference between this stack and the stack that we will create ourselves?

I was expecting that we ourselves had to implement the stack to keep track of the functions local variables and stuff.

3
  • 1
    The processor itself uses the stack for instructions like push, pop, call, ret. You (the programmer) can also use the stack, e.g., to pass parameters to subroutines or to store local variables/arrays. Check your favourite x86 assembly guide for an introduction -- IMO as it is the question is too broad for stackoverflow. Commented Jun 3, 2024 at 11:28
  • 2
    You already used it when you called your strlen. Consult the basic architecture manual section 6.2 STACKS. Ask a specific question if you get stuck. Commented Jun 3, 2024 at 11:29
  • 1
    To complete the prior comments, the x86 builtin stack can be addressed using the sp/esp/rsp registers (in combination with ss segment if the segment matters). For instance, to initialise an array variable on the stack you probably wouldn't loop for push instructions that implicitly use the stack pointer register, but rather subtract the entire array size using one instruction (eg sub rsp, 256) and then copy to the memory explicitly pointed to by rsp using a normal memory copy. Commented Jun 3, 2024 at 12:09

2 Answers 2

1

The operating system creates a process to run an application.  In that process, initially, there's one thread, which has a working stack and stack pointer register before the first instruction in that process is run by the processor.

and the stack that we will create ourselves? I was expecting that we ourselves had to implement the stack to keep track of the functions local variables and stuff.

We don't create the initial stack ourselves, we simply use the operating-system-provided stack to stack things — application programs do "stacking" of things but they don't generally create/prepare those stacks for stacking.  In some sense we can differentiate between the notion of using the stack (e.g. pushing & popping) and establishing some memory as a stack for a thread.

Sign up to request clarification or add additional context in comments.

1 Comment

At least under linux the OS will not provide stack for new threads. The clone syscalls take a pointer to a user allocated memory to use as stack. You can also set up signal handler stack
0

firstly when you want to execute your program in your BASH terminal, BASH will use execve syscall with the directory for your ELF file, then your linux scheduler will create task with user PID identified by the user you are using then it will allocate the stack typically 8 megabytes in linux AFAIK, then the scheduler will context switch to your program entry point by far jump, it will move the stack top to RSP before the far jump and saves your program stack because the scheduler will context switch to other processes, in IA-32 bit mode TSS play role for hardware context if your linux is using IA-32 mode it will far jump using the TSS selector in your linux loaded GDT and it will do hardware task switching by changing registers according to TSS structure loaded using LTR instruction, but in x86_64 mode TSS selector in linux used only for compatibility with 32 bit programs, because in x86_64 long mode cpu does not hardware task switching like in IA-32 mode, the scheduler software will do that. hope this help.

2 Comments

bash forks first (unless you use the bash exec command). That's what creates the new PID. execve executes a new program in an existing process, keeping the PID but replacing it with a fresh process. (And yes the default ulimit -s is 8 MiB so that's how much the kernel allocates, pointing user-space RSP into it below the env vars and argv.)
The TSS is relevant in 64-bit kernels for switching RSP to the kernel stack on interrupts.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.