Не обрабатывает данные с файла - Assembler

Узнай цену своей работы

Формулировка задачи:

Не линкуется выдает ошибки в чем проблема?
.386                    ; 32-битный режим
.model flat, stdcall            ; компиляция в exe-файл с возможностью вызова API
option casemap :none            ; неразличение прописных и строчных символов
 
                    ; содержит значения констант
include C:\masm32\include\windows.inc   ; STD_INPUT_HANDLE,
                    ; STD_OUTPUT_HANDLE
 
include <\masm32\include\kernel32.inc>
include <\masm32\include\user32.inc>
 
includelib <\masm32\lib\kernel32.lib>
includelib <\masm32\lib\user32.lib>
 
.const
 
MEMSIZE equ 65535
 
.data                   ; сегмент данных
 
hfile_write dd ?
hfile_read dd ?
buff_file db 0
 
file_read db "file_read.txt",0
file_write db "file_write.txt",0
file_read_size dd ?  ;размер файла 
size_file_read dd ?  ;количество считанных байт
ByteWritten dd ?
 
hConsoleInput DWORD ?           ; переменные для хранения хэндлов ввода и вывода,
hConsoleOutput DWORD ?          ; названия этих переменных могут быть другими
 
                                ; буфер 1 байт (со значением 0)
Buffer byte 1 dup (0)           ; для вода с клавиатуры 1 символа,
                                ; название буфера может быть другим
 
NumberOfCharsRead DWORD ?       ; переменные для записи числа фактически
NumberOfCharsWritten DWORD ?    ; введенных и выведенных символов,
                                ; названия этих переменных могут быть другими
                                
hMemory HANDLE ?
pMemory DWORD ?
 
msg1 byte "Задача выполненна успешно!"      ; строковая переменная
 
                                ; строковая переменная
msg2 byte "Нажмите Enter, чтобы выйти...", 0    ; заканчивается нулем,
                                ; так как она будет передана
                                ; API-функции CharToOem

msg1310 byte 13, 10         ; перевод строки
ERROR_CreateFile byte "ERROR_CreateFile",0
ERROR_GetFileSize byte "ERROR_GetFileSize",0
ERROR_VirtualAlloc byte "ERROR_VirtualAlloc",0
ERROR_ReadFile byte "ERROR_ReadFile",0
ERROR_WriteFile byte "ERROR_WriteFile",0

.code                   ; сегмент кода
start:

invoke CreateFile, ADDR file_write,
                                GENERIC_WRITE or GENERIC_READ,
                          FILE_SHARE_WRITE or FILE_SHARE_READ,
                                                         NULL,
                                                CREATE_ALWAYS,
                                        FILE_ATTRIBUTE_NORMAL, 
                                                         NULL
;CMP EAX,-1
;JE _ERROR_CreateFile
mov hfile_write, eax
 
invoke CreateFile, ADDR file_read,                        ;открываем файл для чтения для получения дискриптора файла
                                    GENERIC_READ,
                                    FILE_SHARE_READ, 
                                    NULL,
                                    OPEN_EXISTING,
                                    FILE_ATTRIBUTE_READONLY,
                                    NULL
;CMP EAX,-1
;JE _ERROR_CreateFile
mov hfile_read, eax
 
invoke GetFileSize, hfile_read, NULL                      ;получаем размер файла
;CMP EAX,0
;JE _ERROR_GetFileSize
mov file_read_size,eax 

invoke GlobalAlloc,GMEM_MOVEABLE or GMEM_ZEROINIT,MEMSIZE
mov  hMemory,eax ;функция возвращает хэндл на запрошенный блок памяти
 
invoke GlobalLock,hMemory
mov  pMemory,eax ;возвращает указатель на блок памяти

invoke ReadFile, hfile_read,                          ;считываем данные с файла
                                 pMemory, ;Адрес буфера
                                 file_read_size, ;MEMSIZE-1,  ;Размер буфера или сколько байтов нужно прочитать
                                 ADDR size_file_read,  ; Адрес переменной, в которую записывается реальное количество прочитанных данных
                                 NULL
;CMP EAX,0
;JE  _ERROR_ReadFile

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
   mov cx,file_read_size
    mov si,pMemory
    loop1:
    mov al,byte ptr[si]
    cmp al,'а' 
    jl loop2
    sub al,'а'-'a'
    mov byte ptr [si],al
    loop2:
    inc si
    loop loop1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

invoke WriteFile, hfile_write,  
                        pMemory, ; Указатель на буфер, содержащий данные, которые будут записаны в файл
                        size_file_read,     ; Число байтов, которые будут записаны в файл
                        ADDR size_file_read,;ADDR ByteWritten,   ;Указатель на переменную, которая получает число записанных байтов
                        NULL
;CMP EAX,0
;JE _ERROR_WriteFile
                        
invoke CloseHandle, hfile_read
invoke CloseHandle, hfile_write
 
invoke GlobalUnlock,pMemory
invoke GlobalFree,hMemory

invoke AllocConsole         ; запрашиваем у Windows консоль
 
invoke GetStdHandle, STD_INPUT_HANDLE   ; получаем хэндл консоли для ввода
mov hConsoleInput, EAX          ; записываем хэндл в переменную
 
invoke GetStdHandle, STD_OUTPUT_HANDLE  ; получаем хэндл консоли для вывода
mov hConsoleOutput, EAX         ; записываем хэндл в переменную
 
invoke WriteConsoleA,           ; переводим строку в консоли
                      hConsoleOutput,   ; хэндл вывода
                        ADDR msg1310,   ; адрес строки msg1310
                      SIZEOF msg1310,   ; размер строки msg1310
           ADDR NumberOfCharsWritten,   ; сюда функция запишет число символов
                                   0    ; lpReserved передаем, как ноль
 
invoke CharToOem, ADDR msg1, ADDR msg1
 
invoke WriteConsoleA,           ; пишем " Hello, World!"
                      hConsoleOutput,
                           ADDR msg1,
                         SIZEOF msg1,
           ADDR NumberOfCharsWritten,
                                   0

invoke WriteConsoleA,           ; переводим строку
                      hConsoleOutput,
                        ADDR msg1310,
                      SIZEOF msg1310,
           ADDR NumberOfCharsWritten,
                                   0

;invoke CharToOem, ADDR msg2, ADDR msg2 ; перекодируем Win1251 -> DOS

invoke WriteConsoleA,           ; пишем " Нажмите Enter, чтобы выйти..."
                      hConsoleOutput,
                           ADDR msg2,
                   (SIZEOF msg2) - 1,   ; уменьшаем размер строки msg2 на 1 (из-за нуля)
           ADDR NumberOfCharsWritten,
                                   0

invoke ReadConsoleA,            ; ожидаем ввода в консоль
                      hConsoleInput,    ; хэндл ввода
                        ADDR Buffer,    ; адрес буфера
                                  1,    ; вводим 1 символ
             ADDR NumberOfCharsRead,    ; сюда функция запишет число символов
                                  0 ; lpReserved передаем, как ноль

invoke ExitProcess, 0           ; сообщаем системе, что программа окончена

end start               ; завершает сегмент кода
Заменил на
 mov ecx,file_read_size
    mov esi,pMemory
    loop1:
    mov eax,byte ptr[esi] ;error A2070: invalid instruction operands
    cmp eax,'а' 
    jl loop2
    sub eax,'а'-'a'
    mov byte ptr [esi],eax ;error A2070: invalid instruction operands
    loop2:
    inc esi
    loop loop1
теперь выскакивают две ошибки error A2070: invalid instruction operands

Решение задачи: «Не обрабатывает данные с файла»

textual
Листинг программы
;cons4.asm
.586P
;плоская модель памяти
.MODEL FLAT, stdcall
;константы
STD_OUTPUT_HANDLE equ -11
STD_INPUT_HANDLE equ -10
TIME_PERIODIC equ 1 ; тип вызова таймера
;атрибуты цветов
FOREGROUND_BLUE equ 1h ; синий цвет букв
FOREGROUND_GREEN equ 2h ; зеленый цвет букв
FOREGROUND_RED equ 4h ; красный цвет букв
FOREGROUND_INTENSITY equ 8h ; повышенная интенсивность
BACKGROUND_BLUE equ 10h ; синий свет фона
BACKGROUND_GREEN equ 20h ; зеленый цвет фона
BACKGROUND_RED equ 40h ; красный цвет фона
BACKGROUND_INTENSITY equ 80h ; повышенная интенсивность
COL1 = 2h+8h ; цвет выводимого текста
;прототипы внешних процедур
EXTERN wsprintfA:NEAR
EXTERN GetStdHandle@4:NEAR
EXTERN WriteConsoleA@20:NEAR
EXTERN SetConsoleCursorPosition@8:NEAR
EXTERN SetConsoleTitleA@4:NEAR
EXTERN FreeConsole@0:NEAR
EXTERN AllocConsole@0:NEAR
EXTERN CharToOemA@8:NEAR
EXTERN SetConsoleCursorPosition@8:NEAR
210 Часть II. Простые программы, консольные приложения, обработка файлов
EXTERN SetConsoleTextAttribute@8:NEAR
EXTERN ReadConsoleA@20:NEAR
EXTERN timeSetEvent@20:NEAR
EXTERN timeKillEvent@4:NEAR
EXTERN ExitProcess@4:NEAR
;директивы компоновщику для подключения библиотек
includelib c:\masm32\lib\user32.lib
includelib c:\masm32\lib\kernel32.lib
includelib c:\masm32\lib\winmm.lib
;-----------------------------------------------
COOR STRUC
X WORD ?
Y WORD ?
COOR ENDS
;сегмент данных
_DATA SEGMENT
HANDL DWORD ?
HANDL1 DWORD ?
STR2 DB "Пример таймера в консольном приложении",0
STR3 DB 100 dup(0)
FORM DB "Число вызовов таймера: %lu",0
BUF DB 200 dup(?)
NUM DWORD 0
LENS DWORD ? ; количество выведенных символов
CRD COOR <?>
ID DWORD ? ; идентификатор таймера
HWND DWORD ?
_DATA ENDS
;сегмент кода
_TEXT SEGMENT
START:
;перекодировать строку STR2
PUSH OFFSET STR2
PUSH OFFSET STR2
CALL CharToOemA@8
;образовать консоль
;вначале освободить уже существующую
CALL FreeConsole@0
CALL AllocConsole@0
;получить HANDL1 ввода
PUSH STD_INPUT_HANDLE
CALL GetStdHandle@4
MOV HANDL1,EAX
;получить HANDL вывода
PUSH STD_OUTPUT_HANDLE
Глава 2.3. Консольные приложения 211
CALL GetStdHandle@4
MOV HANDL,EAX
;задать заголовок окна консоли
PUSH OFFSET STR2
CALL SetConsoleTitleA@4
;задать цветовые атрибуты выводимого текста
PUSH COL1
PUSH HANDL
CALL SetConsoleTextAttribute@8
;установить таймер
PUSH TIME_PERIODIC ; периодический вызов
PUSH 0
PUSH OFFSET TIME ; вызываемая таймером процедура
PUSH 0 ; точность вызова таймера
PUSH 1000 ; вызов через одну секунду
CALL timeSetEvent@20
MOV ID,EAX
;ждать ввод строки
PUSH 0
PUSH OFFSET LENS
PUSH 200
PUSH OFFSET BUF
PUSH HANDL1
CALL ReadConsoleA@20
;закрыть таймер
PUSH ID
CALL timeKillEvent@4
;закрыть консоль
CALL FreeConsole@0
PUSH 0
CALL ExitProcess@4
;строка - [EBP+08H]
;длина в EBX
LENSTR PROC
ENTER 0,0
PUSH EAX
PUSH EDI
;--------------------
CLD
MOV EDI,DWORD PTR [EBP+08H]
MOV EBX,EDI
MOV ECX,100 ; ограничить длину строки
XOR AL,AL
REPNE SCASB ; найти символ 0
SUB EDI,EBX ; длина строки, включая 0
212 Часть II. Простые программы, консольные приложения, обработка файлов
MOV EBX,EDI
DEC EBX
;--------------------
POP EDI
POP EAX
LEAVE
RET 4
LENSTR ENDP
;процедура вызывается таймером
TIME PROC
PUSHAD ; сохранить все регистры
;установить позицию курсора
MOV CRD.X,0
MOV CRD.Y,10
PUSH CRD
PUSH HANDL
CALL SetConsoleCursorPosition@8
;заполнить строку STR3
PUSH NUM
PUSH OFFSET FORM
PUSH OFFSET STR3
CALL wsprintfA
ADD ESP,12 ; восстановить стек
;перекодировать строку STR3
PUSH OFFSET STR3
PUSH OFFSET STR3
CALL CharToOemA@8
;вывести строку с номером вызова таймера
PUSH OFFSET STR3
CALL LENSTR
PUSH 0
PUSH OFFSET LENS
PUSH EBX
PUSH OFFSET STR3
PUSH HANDL
CALL WriteConsoleA@20
INC NUM
POPAD
RET 20 ; выход с освобождением стека
TIME ENDP
_TEXT ENDS
END START

ИИ поможет Вам:


  • решить любую задачу по программированию
  • объяснить код
  • расставить комментарии в коде
  • и т.д
Попробуйте бесплатно

Оцени полезность:

10   голосов , оценка 4.2 из 5
Похожие ответы