我怎样才能使我的程序不崩溃?

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/leavepush/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