我刚开始使用fasm / x86编程,我开始使用64位样本作为我的项目目标,我需要一些64位xeons。
我从PE64DEMO开始并修改它以添加一个循环,但它在第一次迭代后失败(因为我可以在线收集)Windows api函数可以更改寄存器而不是恢复它们。我也读过我应该保存我需要自己从堆栈中推送和弹出的东西,我评论了推送和弹出,如果我取消注释它们我得到编译时错误说明"错误:非法指令pop eax& #34;
下面的整个文件代码:
; Example of 64-bit PE program
format PE64 GUI
include 'win64a.inc'
entry start
section '.text' code readable executable
start:
sub rsp,8*5 ; reserve stack for API use and make stack dqword aligned
; Assembly code representing expr1 here (for instance mov [count], 0)
mov eax,10
.for_loop_check:
; Assembly code representing expr2 that jumps to .exit_for_loop when false (for instance cmp [count], TOP_VALUE / jae .exit_for_loop when expr2 is "count < TOP_VALUE"). Note that if expr2 is absent then so is the jump.
cmp eax,0
jz .exit_for_loop
;push eax
; body code here
mov r9d,0
lea r8,[_caption]
lea rdx,[_message]
mov rcx,0
call [MessageBoxA]
;pop eax
; Assembly code representing expr3 here (for instance inc [count])
dec eax
jmp .for_loop_check
.exit_for_loop:
mov ecx,eax
call [ExitProcess]
section '.data' data readable writeable
_caption db 'Win64 assembly program',0
_message db 'Hello World!',0
section '.idata' import data readable writeable
library kernel32,'KERNEL32.DLL',\
user32,'USER32.DLL'
include 'api\kernel32.inc'
include 'api\user32.inc'
答案 0 :(得分:1)
我的代码存在多个问题。
首先,由于Rudy Velthuis评论我的代码是非法的并被fasm正确拒绝,push eax
和pop eax
在X64中永远无效,因为eax是32位寄存器而X64不允许推送堆栈的32位值。切换到64位寄存器修复了这个问题。
;change
push eax
pop eax
;to
push rax;
pop rax;
有了它,它现在编译并允许我保持我的注册在整个调用,但代码现在在Windows API中段错误。正如Michael Petch所说,这是因为一旦我推送到堆栈,我打破了以前完成的对齐,而Windows 64要求堆栈为16字节对齐,但是不是修复对齐,解决方案很简单,使用非易失性寄存器在Windows X64 ABI中描述的那些并丢弃使用堆栈进行此操作。
带有更改的最终代码:
format PE64 GUI
include 'win64a.inc'
entry start
section '.text' code readable executable
start:
sub rsp,8*5 ; reserve stack for API use and make stack dqword aligned
;use rbx as counter as it is preserved across windows API calls
mov rbx,10
.for_loop_check:
cmp rbx,0
je .exit_for_loop
mov r9d,0
lea r8,[_caption]
lea rdx,[_message]
mov rcx,0
call [MessageBoxA]
;no more pushing and poping to the stack required, rbx is guaranteed to be unmodified by the windows API
dec rbx
jmp .for_loop_check
.exit_for_loop:
mov ecx,eax
call [ExitProcess]
section '.data' data readable writeable
_caption db 'Win64 assembly program',0
_message db 'Hello World!',0
section '.idata' import data readable writeable
library kernel32,'KERNEL32.DLL',\
user32,'USER32.DLL'
include 'api\kernel32.inc'
include 'api\user32.inc'