我不明白为什么Windows不能在没有崩溃的情况下运行该程序,而且,在可执行程序图标上插入了“shield”图标(管理员模式)。这是我的代码(FASM汇编程序,x86-64):
format PE
entry main
foo:
push ebp
mov ebp, esp
enter 3, 0
mov BYTE [ebp-1], al
mov DWORD [ebp-8], edi
mov DWORD [ebp-12], esi
pop ebp
leave
ret
main:
mov ebp, esp
mov DWORD [ebp-4], edi
mov DWORD [ebp-16], esi
mov al, 97
mov edi, 43
mov esi, 76
call foo
pop ebp
ret
代码对我来说似乎是正确的,我不认为这是问题,也许是一些缺失的指示?我不知道......
PS:奇怪的效果:当我更改程序目录(默认情况下在桌面上)时,盾牌消失了...我真的不明白...
注意:也许对你而言很明显,但对我来说并非如此。我的互联网搜索没有找到任何结论。
[代码编辑1]:
另一个程序的例子,更简化,没有明显原因崩溃:
format PE console
org 100h
mov ah,09
mov dx,msg
int 21h
mov ah,08
int 21h
int 20h
msg db "hello world!$"
[编辑代码2]:
format PE
entry main
main:
push ebp
mov ebp, esp
mov DWORD [ebp-4], edi
mov DWORD [ebp-16], esi
mov edi, 8
call square
pop ebp
ret
square:
push ebp
mov ebp, esp
mov DWORD [ebp-4], edi
pop ebp
ret
答案 0 :(得分:3)
嗯,您正尝试以两种不同的独立方式设置堆栈框架 - enter/leave
和push/pop
。因此,您只是弄乱堆栈,因此程序在ret
指令上返回错误的地址。
只使用其中一种方法,不要忘记设置退出代码:
format PE
entry main
foo:
enter 12, 0
mov BYTE [ebp-1], al
mov DWORD [ebp-8], edi
mov DWORD [ebp-12], esi
leave
ret
main:
enter 16, 0
mov DWORD [ebp-4], edi
mov DWORD [ebp-16], esi
mov al, 97
mov edi, 43
mov esi, 76
call foo
leave
xor eax, eax ; exit code
ret
format PE
entry main
foo:
push ebp
mov ebp, esp
sub esp, 12
mov BYTE [ebp-1], al
mov DWORD [ebp-8], edi
mov DWORD [ebp-12], esi
mov esp, ebp
pop ebp
ret
main:
push ebp
mov ebp, esp
sub esp, 16
mov DWORD [ebp-4], edi
mov DWORD [ebp-16], esi
mov al, 97
mov edi, 43
mov esi, 76
call foo
mov esp, ebp
pop ebp
xor eax, eax ; exit code
ret
这两种变体都不会崩溃并且会正常终止,尽管它们实际上没有任何用处。你究竟想要实现什么目标?
P.S。您的dos示例也可以,但您需要使用一些不同的选项进行编译:
format binary as "com"
org 100h
mov ah,09
mov dx,msg
int 21h
mov ah,08
int 21h
int 20h
msg db "hello world!$"
现在在DOS中编译并运行结果.com
文件或在Windows或Linux中使用DosBox:
$dosbox myprog.com