I assumed I had push’ed something without popping it, or vice versa, but I can’t find anything wrong! I write to the console with a call to a dll that links properly, and I inexplicably am in no mans land… (address 0x0000000000000000)
I’ve put some sleeps in, and I’m sure that the api call WriteConsoleA is returning. It’s on my last ret under the print function.
Any ideas?
.exe:
extern FreeConsole
extern Sleep
extern ExitProcess
extern print
extern newconsole
extern strlen
section .data BITS 64
title: db 'Consolas!',0
message: db 'Hello, world',0,0
section .text bits 64
global Start
Start:
mov rcx, title
call newconsole
mov rcx, 1000
call Sleep
mov rcx, message
call print
mov rcx, 10000
call Sleep
call FreeConsole
xor rcx, rcx
call ExitProcess
.dll:
extern AllocConsole
extern SetConsoleTitleA
extern GetStdHandle
extern WriteConsoleA
extern Sleep
export newconsole
export strlen
export print
section .data BITS 64
console.writehandle: dq 0
console.readhandle: dq 0
console.write.result: dq 0
section .text BITS 64
global strlen
strlen:
push rax
push rdx
push rdi
mov rdi, rcx
xor rax, rax
mov rcx, dword -1
cld
repnz scasb
neg rcx
sub rcx, 2
pop rdi
pop rdx
pop rax
ret
global print
print:
mov rbp, rsp
push rcx
call strlen
mov r8, rcx
pop rdx
mov rcx, [console.writehandle]
mov r9, console.write.result
push qword 0
call WriteConsoleA
ret
global newconsole
newconsole:
push rax
push rcx
call AllocConsole
pop rcx
call SetConsoleTitleA
mov rcx, -11
call GetStdHandle
mov [console.writehandle], rax
pop rax
ret
I assume you’re talking about this function:
The x64 ABI requires that stack space is reserved even for parameters passed in registers.
WriteConsoleAis free to use those stack locations for whatever it wants – so you need to make sure that you’ve adjusted the stack appropriately. As it stands, you’re pushing only the last reserved pointer parameter. I think something like the following will do the trick for you:See http://msdn.microsoft.com/en-us/library/ms235286.aspx (emphasis added):