环境,赢7.使用NASM,gcc(MINGW)
我有以下非常简单的汇编源:
SECTION .data ; initialized data
fname: db "c:\asmplus\tsources\s1.txt", 0
fread: db "r", 0
mopf: db "[FILE] open: %s", 10, 0
SECTION .text ; code
extern _fopen
extern _printf
push DWORD fname
push DWORD mopf
call _printf
add esp, 8 ; clean up stack use
mov DWORD [esp], fname
mov DWORD [esp + 4], fread
call _fopen
我得到以下输出:
[FILE] open:c:\ asmplus \ tsources \ s1.txt
...然后是一个Windows对话框,说明应用程序崩溃了。我没有任何类型的调试器可用,所以我将其分解为最简单的源并尝试它就像这样。该文件可用且未打开。我的代码有什么特别的错误吗?
更新
完整代码添加@Jester的请求
parse.asm
SECTION .data ; initialized data
mend: db 10, "*** END ***", 10, 0
mopf: db "open_file", 0
mcll: db "[MAIN] call %s: %s", 10, 0
mret: db "[MAIN] ret: %d", 10, 0
SECTION .text use32 ; code
extern open_file
extern _printf
global _main
_main:
; stash base stack pointer
push ebp
mov ebp, esp
mov eax, [ebp + 8] ; num args
mov ebx, [ebp + 12] ; address of args (strings)
mov ecx, 0 ; init counter register to 0
.do:
push ebp
push eax
push ecx
mov [c], ecx
; only expect args[1] to contain the file name
mov eax, 1
cmp eax, [c]
jne .cont
jmp .openFile
.cont:
pop ecx
pop eax
pop ebp
add ebx, 4 ; move to next arg
inc ecx ; increment counter
cmp ecx, eax
jne .do
.openFile:
push DWORD [ebx]
push DWORD mopf
push DWORD mcll
call _printf
add esp, 12
push DWORD [ebx]
call open_file ; should push result to eax
mov eax, [ebp + 8] ; stash file handle from stack
mov [fh], eax ; into fh variable
add esp, 4 ; clean up stack
push DWORD [fh]
push DWORD mret
call _printf
add esp, 8 ; clean up stack
.end:
push DWORD mend
call _printf
; restore base stack pointer
mov esp, ebp
pop ebp
SECTION .bss ; uninitialized data
c: resd 1
fh: resd 1
fileops.asm
; Contains file operations:
; open_file
; ... TODO: read/write/close
SECTION .data ; initialized data
fread: db "r", 0
merr: db "[FILE] error [%d:%d] %s", 10, 0
mopf: db "[FILE] open: %s", 10, 0
SECTION .text ; code
extern _fopen
extern _printf
global open_file
open_file:
; stash base stack pointer
push ebp
mov ebp, esp
mov eax, [ebp + 8]
mov [fnarg], eax
push DWORD [fnarg]
push DWORD mopf
call _printf
add esp, 8
; open file
push DWORD fread
push DWORD [fnarg]
call _fopen
add esp, 8
push DWORD [eax]
xor eax, eax
.done:
; restore base stack pointer
mov esp, ebp
pop ebp
ret
SECTION .bss ; uninitialized data
fnarg: resb 128 ; reserve 128 bytes for file name
fhndl: resd 1
当前输出:
D:\ asmplus>。\ exes \ parse。\ tsources \ s1.txt
[MAIN]调用open_file:。\ tsources \ s1.txt
[文件]打开:。\ tsources \ s1.txt
[MAIN] ret:2
答案 0 :(得分:1)
那是你的所有代码吗?如果您之后没有任何内容,它当然会崩溃,因为您不能通过call _exit
或仅仅返回来正确终止您的程序。
另请注意,您要通过add esp, 8
清理堆栈,这样您就不再有可用空间来尝试将参数移入。您正在覆盖堆栈中的内容,例如返回地址,如果您尝试从函数返回,则会导致问题。您可以将add
向下移动到call _fopen
之后,当您真的不再需要这些广告位时。
更正的版本看起来更像是:
push DWORD fname
push DWORD mopf
call _printf
mov DWORD [esp], fname
mov DWORD [esp + 4], fread
call _fopen
add esp, 8 ; clean up stack use
xor eax, eax ; 0 return value
ret
-OR -
push DWORD fname
push DWORD mopf
call _printf
add esp, 8 ; clean up stack use
push DWORD fread
push DWORD fname
call _fopen
add esp, 8 ; clean up stack use
xor eax, eax ; 0 return value
ret