Take for example a short program where I was testing this today I wanted to do the same thing back up all the registers before I started to do syscalls that we just learned about. So I first attempted pusha and popa something I found in a old IA-32 Intel Architecture Software Developer's Manual. However it did not work. I have tested this manually and that works however.
#Author: Jonathan Lee
#Professor: Devin Cook
#CSC35
#4-27-23
#practicesyscall.asm
.intel_syntax noprefix
.data
Message:
.asciz "Learning about system calls.\n"
.text
.global _start
_start:
pusha #facilitates saving the current general purpose registers only 32 bit processor
mov rax, 1
mov rdi, 1
lea rsi, Message
mov rdx, 30
syscall
popa #facilitates restoring the registers only 32 bit processor
mov rax, 60
mov rdi, 0
syscall
This is the result when it is compiled with x64:
practicesyscall.asm: Assembler messages:
practicesyscall.asm:19: Error: `pusha' is not supported in 64-bit mode
practicesyscall.asm:25: Error: `popa' is not supported in 64-bit mode
Without the pusha and popa mnemonics it works and this is the result:
Learning about system calls.
This will work for x32 mode:
Intel Ref Document
However it does work manually if you wanted to try this method:
#Jonathan Lee
#CSC35
#Professor Cook
#3-31-23
#Practice NON credit assignment
.intel_syntax noprefix
.data
Intro:
.ascii "Hello world my name is Jonathan Lee\n\n SAC STATE STINGERS UP\n\n"
.ascii "This program is to aid in learning more about stacks inside of assembly language.\n"
.ascii "Register RSP is used to point to the top of the stack. If you use (push) it will load the stack and move the pointer (RSP) automatically.\n"
.ascii "The stack counts down not up in assembly language.\n"
.ascii "This is the current RSP point prior to loading a stack or program run:---------------------> \0"
NewLine:
.ascii "\n\0"
StackLoad:
.ascii "Program will now load 1-14 into registers and push to the stack after it will write the register values and current RSP pointer value again.\n"
.ascii "This will not use registers RSP/RDI they are in use for stack pointer and class subroutines.\n\0"
ZeroLoad:
.ascii "Program will now load 0 into all registers and write register values after to show values are now stored in memory not registers.\n\0"
PopLoad:
.ascii "Note RSP is still using the same value. The program will now pop the stack and reverse load the values into the registers, after will write register values.\n"
.ascii "Last In First Out.\n\0"
RSPAddress:
.ascii "This is the current next available RSP Pointer Memory Address on top of stack:-------------> \0"
PostStack:
.ascii "This is the the current next available RSP Pointer Memory Address after stack is popped:---> \0"
PreExit:
.ascii "\nNote that the RSP is now pointing to the same memory address value as when the program started.\n\n\0"
.text
.global _start
_start:
call ClearScreen
lea rdi, NewLine
call WriteString
lea rdi, Intro
call WriteString
mov rdi, rsp
call WriteHex
lea rdi, NewLine
call WriteString
mov rax, 1
mov rbx, 2
mov rcx, 3
mov rdx, 4
mov rsi, 5
mov rdi, 6
mov rbp, 7
#rsp index use
mov r8, 8
mov r9, 9
mov r10, 10
mov r11, 11
mov r12, 12
mov r13, 13
mov r14, 14
mov r15, 15
lea rdi, StackLoad
call WriteString
push rax
push rbx
push rcx
push rdx
push rsi
push rbp
push r8
push r9
push r10
push r11
push r12
push r13
push r14
push r15
call WriteRegisters
lea rdi, RSPAddress
call WriteString
mov rdi, rsp
call WriteHex
lea rdi, NewLine
call WriteString
lea rdi, ZeroLoad
call WriteString
mov rax, 0
mov rbx, 0
mov rcx, 0
mov rdx, 0
mov rsi, 0
mov rbp, 0
mov r8, 0
mov r9, 0
mov r10, 0
mov r11, 0
mov r12, 0
mov r13, 0
mov r14, 0
mov r15, 0
call WriteRegisterslea rdi, RSPAddress
call WriteString
mov rdi, rsp
call WriteHex
lea rdi, NewLine
call WriteString
lea rdi, PopLoad
call WriteString
pop rax
pop rbx #Last In First Out
pop rcx
pop rdx
pop rsi
pop rbp
pop r8
pop r9
pop r10
pop r11
pop r12
pop r13
pop r14#flip stack
pop r15
call WriteRegisters
lea rdi, PostStack
call WriteString
mov rdi, rsp
call WriteHex
lea rdi, NewLine
call WriteString
lea rdi, PreExit
call WriteString
call Exit
And the result would be:
Hello world my name is Jonathan Lee
SAC STATE STINGERS UP
This program is to aid in learning more about stacks inside of assembly language.
Register RSP is used to point to the top of the stack. If you use (push) it will load the stack and move the pointer (RSP) automatically.
The stack counts down not up in assembly language.
This is the current RSP point prior to loading a stack or program run:---------------------> 00007FFEC3675420
Program will now load 1-14 into registers and push to the stack after it will write the register values and current RSP pointer value again.
This will not use registers RSP/RDI they are in use for stack pointer and class subroutines.
RAX : 0000000000000001 R8 : 0000000000000008
RBX : 0000000000000002 R9 : 0000000000000009
RCX : 0000000000000003 R10 : 000000000000000A
RDX : 0000000000000004 R11 : 000000000000000B
RDI : 0000000000600AA5 R12 : 000000000000000C
RSI : 0000000000000005 R13 : 000000000000000D
RBP : 0000000000000007 R14 : 000000000000000E
RSP : 00007FFEC36753A0 R15 : 000000000000000F
This is the current next available RSP Pointer Memory Address on top of stack:-------------> 00007FFEC36753B0
Program will now load 0 into all registers and write register values after to show values are now stored in memory not registers.
RAX : 0000000000000000 R8 : 0000000000000000
RBX : 0000000000000000 R9 : 0000000000000000
RCX : 0000000000000000 R10 : 0000000000000000
RDX : 0000000000000000 R11 : 0000000000000000
RDI : 0000000000600B90 R12 : 0000000000000000
RSI : 0000000000000000 R13 : 0000000000000000
RBP : 0000000000000000 R14 : 0000000000000000
RSP : 00007FFEC36753A0 R15 : 0000000000000000
This is the current next available RSP Pointer Memory Address on top of stack:-------------> 00007FFEC36753B0
Note RSP is still using the same value. The program will now pop the stack and reverse load the values into the registers, after will write register values.
Last In First Out.
RAX : 000000000000000F R8 : 0000000000000009
RBX : 000000000000000E R9 : 0000000000000008
RCX : 000000000000000D R10 : 0000000000000007
RDX : 000000000000000C R11 : 0000000000000005
RDI : 0000000000600C13 R12 : 0000000000000004
RSI : 000000000000000B R13 : 0000000000000003
RBP : 000000000000000A R14 : 0000000000000002
RSP : 00007FFEC3675410 R15 : 0000000000000001
This is the the current next available RSP Pointer Memory Address after stack is popped:---> 00007FFEC3675420
Note that the RSP is now pointing to the same memory address value as when the program started.
Long story short, you can just load the registers manually one by one into the stack and pop them after to restore it if so required.