我怎样才能使我的程序不崩溃?
How can I make that my program does not crash?
我不明白为什么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
好吧,您正在尝试以两种不同的独立方式设置堆栈帧 - enter/leave
和 push/pop
。结果你只是弄乱了堆栈,所以程序 returns 在 ret
指令的错误地址上。
只使用其中一种方法,不要忘记设置退出代码:
变体 1
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
变体 2
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 或 Windows 或 Linux:
中使用 DosBox 编译并 运行 结果 .com
文件
$dosbox myprog.com
我不明白为什么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
好吧,您正在尝试以两种不同的独立方式设置堆栈帧 - enter/leave
和 push/pop
。结果你只是弄乱了堆栈,所以程序 returns 在 ret
指令的错误地址上。
只使用其中一种方法,不要忘记设置退出代码:
变体 1
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
变体 2
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 或 Windows 或 Linux:
中使用 DosBox 编译并 运行 结果.com
文件
$dosbox myprog.com