初学汇编,编译出错求助

qq7315 2012-01-01 06:02:52
正在看《windows环境下32位汇编语言程序设计》,第350页的小程序FormatText,看到ReadFile函数只能一次读取指定个数字符,
想换成一次读取一行的函数,网上找到些代码,替换后编译出错,
错误信息:
Microsoft (R) Program Maintenance Utility Version 8.00.50727.762
Copyright (C) Microsoft Corporation. All rights reserved.

ml /c /coff FormatText.asm
Microsoft (R) Macro Assembler Version 6.14.8444
Copyright (C) Microsoft Corp 1981-1997. All rights reserved.

Assembling: FormatText.asm
FormatText.asm(136) : error A2155: cannot use 16-bit register with a 32-bit addr
ess
NMAKE : fatal error U1077: 'D:\masm32\bin\ml.EXE' : return code '0x1'
Stop.

红色部分为自定义的函数,求解
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; Sample code for < Win32ASM Programming 2nd Edition>
; by 罗云彬, http://asm.yeah.net
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; FormatText.asm
; 文件读写例子 —— 将 Unix 格式的文本文件(以0ah换行)转换成 PC 格式
; 的文本文件(以0dh,0ah换行),读写文件操作使用文件操作函数。
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 使用 nmake 或下列命令进行编译和链接:
; ml /c /coff FormatText.asm
; rc FormatText.rc
; Link /subsystem:windows FormatText.obj FormatText.res
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
.386
.model flat, stdcall
option casemap :none
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; Include 文件定义
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
include windows.inc
include user32.inc
includelib user32.lib
include kernel32.inc
includelib kernel32.lib
include comdlg32.inc
includelib comdlg32.lib
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; Equ 等值定义
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
ICO_MAIN equ 1000
DLG_MAIN equ 100
IDC_FILE equ 101
IDC_BROWSE equ 102
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 数据段
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
.data?

hInstance dd ?
hWinMain dd ?
szFileName db MAX_PATH dup (?)

.const
szFileExt db '文本文件',0,'*.txt',0,0
szNewFile db '.new.txt',0
szErrOpenFile db '无法打开源文件!',0
szErrCreateFile db '无法创建新的文本文件!',0
szSuccees db '文件转换成功,新的文本文件保存为',0dh,0ah,'%s',0
szSucceesCap db '提示',0
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 代码段
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

.code
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 在缓冲区中找出一行数据,处理换行并保存
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
_FormatText proc uses esi _lpData,_dwSize,_hFile
local @szBuffer[128]:byte,@dwBytesWrite

mov esi,_lpData
mov ecx,_dwSize
lea edi,@szBuffer
xor edx,edx
cld
_LoopBegin:
or ecx,ecx
jz _WriteLine
lodsb
dec ecx
cmp al,0dh ;遇到0dh则丢弃
jz _LoopBegin
cmp al,0ah ;遇到0ah则扩展为0dh,0ah
jz _LineEnd
stosb
inc edx
cmp edx,sizeof @szBuffer-2
jae _WriteLine ;行缓冲区满则保存
jmp _LoopBegin
_LineEnd:
mov ax,0a0dh
stosw
inc edx
inc edx
_WriteLine:
push ecx
.if edx
invoke WriteFile,_hFile,addr @szBuffer,edx,addr @dwBytesWrite,NULL
.endif
lea edi,@szBuffer
xor edx,edx
pop ecx
or ecx,ecx
jnz _LoopBegin
ret

_FormatText endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
;读取文件中的一行数据到缓冲区
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
_ReadLine proc hFile, cBuf, ccSize

local @iRead

pushf
push ebx
push ecx
push edx
push esi

mov @iRead, 0
cld

mov edx, cBuf
mov esi, edx
mov ebx, hFile
l_read1:
mov ah, 3fh
mov cx, 1
int 21h ; 读入一个字符
jc l_ret ; 读入出错的话, 直接返回
lodsb
cmp al, 0dh ; 是回车?
je l_0d
cmp al, 0ah ; 是换行
je l_0a
inc edx
inc @iRead
jmp l_read1 ; 不是,转去读入下一字符

l_0d:
mov ah, 3fh
mov cx, 1
int 21h ; 刚才是回车, 再读入下一字符
jc l_ret
cmp byte ptr [si][-1], 0ah ; 看看是否是换行
je l_ret
mov ax, 4201h
mov cx, -1 ; 如果不是换行, 文件指针回退一, 即将刚才那个字符返给文件里
mov dx, cx
int 21h
jmp l_ret

l_0a:

l_ret:
pop esi
pop edx
pop ecx
pop ebx
popf

mov eax, @iRead

ret

_ReadLine endp

;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
_ProcFile proc
local @hFile,@hFileNew,@dwBytesRead
local @szNewFile[MAX_PATH]:byte
local @szReadBuffer[512]:byte

;********************************************************************
; 打开文件
;********************************************************************
invoke CreateFile,addr szFileName,GENERIC_READ,FILE_SHARE_READ,0,\
OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0
.if eax == INVALID_HANDLE_VALUE
invoke MessageBox,hWinMain,addr szErrOpenFile,NULL,MB_OK or MB_ICONEXCLAMATION
ret
.endif
mov @hFile,eax
;********************************************************************
; 创建输出文件
;********************************************************************
invoke lstrcpy,addr @szNewFile,addr szFileName
invoke lstrcat,addr @szNewFile,addr szNewFile
invoke CreateFile,addr @szNewFile,GENERIC_WRITE,FILE_SHARE_READ,\
0,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,0
.if eax == INVALID_HANDLE_VALUE
invoke MessageBox,hWinMain,addr szErrCreateFile,NULL,MB_OK or MB_ICONEXCLAMATION
invoke CloseHandle,@hFile
ret
.endif
mov @hFileNew,eax
;********************************************************************
; 循环读出文件并处理每个字节
;********************************************************************
xor eax,eax
mov @dwBytesRead,eax
.while TRUE
lea esi,@szReadBuffer
; invoke ReadFile,@hFile,esi,sizeof @szReadBuffer,addr @dwBytesRead,0
;************************************************************************
;自定义函数
;************************************************************************
invoke _ReadLine,@hFile,esi,sizeof @szReadBuffer
mov @dwBytesRead,eax
;************************************************************************

.break .if ! @dwBytesRead
invoke _FormatText,esi,@dwBytesRead,@hFileNew
.endw
invoke CloseHandle,@hFile
invoke CloseHandle,@hFileNew
invoke wsprintf,addr @szReadBuffer,addr szSuccees,addr @szNewFile
invoke MessageBox,hWinMain,addr @szReadBuffer,addr szSucceesCap,MB_OK
ret

_ProcFile endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
_ProcDlgMain proc uses ebx edi esi hWnd,wMsg,wParam,lParam
local @stOpenFileName:OPENFILENAME

mov eax,wMsg
.if eax == WM_CLOSE
invoke EndDialog,hWnd,NULL
;********************************************************************
.elseif eax == WM_INITDIALOG
push hWnd
pop hWinMain
invoke LoadIcon,hInstance,ICO_MAIN
invoke SendMessage,hWnd,WM_SETICON,ICON_BIG,eax
invoke SendDlgItemMessage,hWnd,IDC_FILE,EM_SETLIMITTEXT,MAX_PATH,0
;********************************************************************
.elseif eax == WM_COMMAND
mov eax,wParam
.if ax == IDC_BROWSE
;********************************************************************
invoke RtlZeroMemory,addr @stOpenFileName,sizeof OPENFILENAME
mov @stOpenFileName.lStructSize,SIZEOF @stOpenFileName
mov @stOpenFileName.Flags,OFN_FILEMUSTEXIST or OFN_PATHMUSTEXIST
push hWinMain
pop @stOpenFileName.hwndOwner
mov @stOpenFileName.lpstrFilter,offset szFileExt
mov @stOpenFileName.lpstrFile,offset szFileName
mov @stOpenFileName.nMaxFile,MAX_PATH
invoke GetOpenFileName,addr @stOpenFileName
.if eax
invoke SetDlgItemText,hWnd,IDC_FILE,addr szFileName
.endif
;********************************************************************
.elseif ax == IDC_FILE
invoke GetDlgItemText,hWnd,IDC_FILE,addr szFileName,MAX_PATH
mov ebx,eax
invoke GetDlgItem,hWnd,IDOK
invoke EnableWindow,eax,ebx
;********************************************************************
.elseif ax == IDOK
call _ProcFile
.endif
;********************************************************************
.else
mov eax,FALSE
ret
.endif
mov eax,TRUE
ret

_ProcDlgMain endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
start:
invoke GetModuleHandle,NULL
mov hInstance,eax
invoke DialogBoxParam,hInstance,DLG_MAIN,NULL,offset _ProcDlgMain,NULL
invoke ExitProcess,NULL
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
end start
...全文
89 2 打赏 收藏 转发到动态 举报
写回复
用AI写文章
2 条回复
切换为时间正序
请发表友善的回复…
发表回复
pianoid 2012-01-01
  • 打赏
  • 举报
回复
出错信息已经说的很明白了,在第136行,si是16位寄存器,而-1是32位地址偏移,所以编译出错了,向ls说的那样把si换成32位寄存器esi就可以编译了。
mlj0381 2012-01-01
  • 打赏
  • 举报
回复
cmp byte ptr [esi][-1], 0ah ; 看看是否是换行 编译能通过,不知道能不能正常运行。试试吧

21,458

社区成员

发帖
与我相关
我的任务
社区描述
汇编语言(Assembly Language)是任何一种用于电子计算机、微处理器、微控制器或其他可编程器件的低级语言,亦称为符号语言。
社区管理员
  • 汇编语言
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧