Environment, Win 7. Использование NASM, GCC (MinGW)Почему fopen не удается выполнить простой вызов сборки? [Внимание: длинный источник сборки]
У меня есть следующие очень простой источник сборки:
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] открыто: с: \ asmplus \ tsources \ s1.txt
... а затем диалог Windows, произнося приложения час как разбился. У меня нет никакого отладочного устройства, поэтому я пропустил его до самого простого источника и попробовал его именно так. Файл доступен, а не открыт. Что-то не так с моим кодом?
UPDATE
полный код добавил @ просьбе шута
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 \ синтаксического анализа \ tsources \ s1.txt
[MAIN] вызов open_file:... \ Tsources \ s1.txt
[FILE] открыто:. \ Tsources \ s1.txt
[MAIN] RET: 2
Я завершающего правильно. Базовый тест перед реализацией 'call _fopen' напечатал желаемый результат и был правильно завершен. Именно в этом конкретном разделе приложение сбой. :) – IAbstract
Как я уже сказал, если «закончить правильно» вы имеете в виду использование «ret», то это будет ошибкой, потому что ваш код перепутал стек. Опубликовать полный код, если вы не знаете, где проблема, в каком случае решить ее самостоятельно: P – Jester
Вы помогли мне выяснить, что было не так. В моем исходном приложении я передаю имя файла аргумента команды в мою функцию open_file. Полагаю, я обнаружил, что некорректно переносил аргумент из стека и в переменную. Кажется, он работает сейчас. Благодаря! – IAbstract