61
Programming with NASM / Re: Things to do in _start
« Last post by fredericopissarra on March 07, 2024, 04:18:50 PM »That makes sense. When you say, main() has a misaligned RSP, how do you know? Is it because of the way nasm puts the binary together? I am doing pure Linux at the moment and using syscalls with _start, not doing the pseudo C, so I gather from what you're saying that I don't need the prolog. But, I will once I switch to main for the pseudo C stuff, so I'm curious how you know.
It is described in the ABIs. And you can see for yourself:
Code: [Select]
; test_win64.asm
;
; c:\work> nasm -fwin64 -o test_win64.o test_win64.asm
; c:\work> ld -s -o test_win64.exe test_win64.o -lkernel32
;
bits 64
default rel
section .data
buffer:
db '0x'
times 16 db '0'
db `\n`
bufferLength equ $ - buffer
section .text
extern __imp_GetStdHandle
extern __imp_WriteConsoleA
extern __imp_ExitProcess
global _start
_start:
; sub rsp,8 ; align to DQWORD, if needed
mov rdx,rsp
lea rcx,[buffer+2]
call u64toStr
mov rcx,-11
call [__imp_GetStdHandle]
mov rcx,rax
lea rdx,[buffer]
mov r8d,bufferLength
xor r9,r9
push r9
call [__imp_WriteConsoleA]
xor ecx,ecx
jmp [__imp_ExitProcess]
; Destroys RAX, RDX and RDI.
align 4
u64toStr:
lea rdi,[rcx+15]
jmp .test
.loop:
mov rax,rdx
and al,0x0f
add al,'0'
cmp al,'9'
jbe .skip
add al,7
.skip:
mov [rdi],al
shr rdx,4
dec rdi
.test:
cmp rdi,rcx
jae .loop
ret
bits 64
default rel
section .data
buffer:
db '0x'
times 16 db '0'
db `\n`
bufferLength equ $ - buffer
section .text
extern __imp_GetStdHandle
extern __imp_WriteConsoleA
extern __imp_ExitProcess
global _start
_start:
; sub rsp,8 ; align to DQWORD, if needed
mov rdx,rsp
lea rcx,[buffer+2]
call u64toStr
mov rcx,-11
call [__imp_GetStdHandle]
mov rcx,rax
lea rdx,[buffer]
mov r8d,bufferLength
xor r9,r9
push r9
call [__imp_WriteConsoleA]
xor ecx,ecx
jmp [__imp_ExitProcess]
; Destroys RAX, RDX and RDI.
align 4
u64toStr:
lea rdi,[rcx+15]
jmp .test
.loop:
mov rax,rdx
and al,0x0f
add al,'0'
cmp al,'9'
jbe .skip
add al,7
.skip:
mov [rdi],al
shr rdx,4
dec rdi
.test:
cmp rdi,rcx
jae .loop
ret
Code: [Select]
; test_sysv.asm
;
; $ nasm -felf64 -o test_sysv.o test_sysv.asm
; $ ld -s -o test_sysv test_sysv.o
;
bits 64
default rel
section .data
buffer:
db '0x'
times 16 db '0'
db `\n`
bufferLength equ $ - buffer
section .text
global _start
_start:
; NOTA: RSP já está alinhado por DQWORD (SysV ABI)!
mov rsi,rsp
lea rdi,[buffer+2]
call u64toStr
mov eax,1
mov edi,eax
lea rsi,[buffer]
mov edx,bufferLength
syscall
xor edi,edi
mov eax,60
syscall
align 4
u64toStr:
lea rcx,[rdi+15]
jmp .test
.loop:
mov rax,rsi
and al,0x0f
add al,'0'
cmp al,'9'
jbe .skip
add al,7
.skip:
mov [rcx],al
shr rsi,4
dec rcx
.test:
cmp rcx,rdi
jae .loop
ret
Running both of them (using MinGW64 for Windows):Code: [Select]
c:\work> nasm -fwin64 -o test_win64.o test_win64.asm
c:\work> ld -s -o test_win64.exe test_win64.o -lkernel32
c:\work> test_win64
0x00000034601FF858
Code: [Select]
$ nasm -felf64 -o test_sysv.o test_sysv.asm
$ ld -s -o test_sysv test_sysv.o
$ ./test_sysv
0x00007FFD2BBF2D90
Notice the first 4 bits...Anyway, see the SysV ABI for x86-64, here, topic 3.4.1 (in Stack State):
Quote
%rsp "The stack pointer holds the address of the byte with lowest address which is part of
the stack. It is guaranteed to be 16-byte aligned at process entry."
On SysV ABI RSP points to argc, argv, envp, main-like arguments (see the ABI).
For MS-ABI you'll have to search the MSDN.