700字范文,内容丰富有趣,生活中的好帮手!
700字范文 > win32汇编 实现UNIX文件格式转换WINDOWS文件格式 的功能

win32汇编 实现UNIX文件格式转换WINDOWS文件格式 的功能

时间:2019-05-19 03:35:05

相关推荐

win32汇编  实现UNIX文件格式转换WINDOWS文件格式 的功能

我们应该都知道UNIX环境下的文本文档中的回车加换行是直接由 "0ah" 实现的,而windows环境下的回车换行需要"0dh,0ah" 实现,所以如果把UNIX环境下的文本文档拿过来在WINDOWS环境下查看,那么文本的显示格式就乱了,结果是windows读不懂UNIX环境下的换行符,他以为是一行,事实也就是文本显示的就是一行,只能靠水平滚动条来回拖动查看,的确看着不爽,这次利用WIN32汇编语言结合windows环境下内存管理的内容实现将UNIX文件格式转换为windows环境下的文件格式 的功能。下面看一下实现该功能的几个分步操作。

上面就是实现该功能的具体分支,下面首先来看一下资源文件中的问题:

资源文件中在使用ResEdit工具编写的时候,在对话框的风格中总会有一个风格DS-SHELLFONT,这个风格总是无效的,在用RadASM编译ResEdit工具编写的资源脚本的时候总会出现未找到定义的风格DS_SHELLFONT

也就是说在头文件的一些定义中并没有该风格的定义,总会出错,然后我果断的把这个风格从资源代码中移除。。。,结果呢,资源脚本可以编译运行了,那么这个风格到底是几个意思,如果要想用它的话怎么办呢?

我们还是来看一下MSDN博客是怎么说的,下面是连接:https://blogs./oldnewthing/0204-00/?p=36523/

具体可以参考一下,说的貌似很有道理,文件的版本需要更高才可以。

资源文件就这么多问题其他的就是以前常用的操作了,很熟练了。下面具体看一下资源脚本代码:

/

/ Generated by ResEdit 1.6.6// Copyright (C) -// #include <windows.h>#include <commctrl.h>#include <richedit.h>#include "resource.h"//// Dialog resources//LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRALIDD_DIALOG1 DIALOG 0, 0, 186, 95STYLE DS_3DLOOK | DS_CENTER | DS_CONTEXTHELP | DS_MODALFRAME | DS_SETFONT | WS_CAPTION | WS_VISIBLE | WS_GROUP | WS_TABSTOP | WS_POPUP | WS_SYSMENUCAPTION "UNIX Text file -> PC Text file"FONT 8, "Ms Shell Dlg"{PUSHBUTTON"开始", IDOK, 127, 70, 46, 18, 0, WS_EX_DLGMODALFRAMEPUSHBUTTON"浏览", IDC_BROWSE, 49, 70, 44, 18, NOT WS_TABSTOP | BS_VCENTER | BS_MULTILINE, WS_EX_DLGMODALFRAME | WS_EX_STATICEDGELTEXT "文件名", 0, 17, 20, 43, 11, SS_LEFT, WS_EX_LEFTEDITTEXT IDC_FILE, 50, 18, 135, 16, ES_AUTOHSCROLL, WS_EX_DLGMODALFRAME | WS_EX_ACCEPTFILES}//// Icon resources//LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRALIDI_ICON1ICON "icon2.ico"

本来想上传资源文件显示的截图的,但是上传文件时老出错误,就不传了。

下面看一下实现程序代码中遇到的问题:

这次程序中首先遇到的问题就是在处理缓冲区中的一单行的文本的时候,好多问题,下面来看一下子程序

_FormatTextproc uses esi _lpData,_dwSize,_hFile;首先该子程序需要三个参数,该子函数在_ProcFile()子程序中调用,_lpdata 就是将 一行文本读入到缓 冲区中,_lpData指向这个缓冲区,_dwSize 指向实际读入的 字节数,_hFile就是文件名只不过这个文件名是存放在缓冲区中LOCAL@szBuffer[128]:byte,@dwBytesWritemov esi,_lpData ;esi寄存器作为源操作内容存放的开始地址mov ecx,_dwSize ;作为循环的计数lea edi,@szBuffer ;另开一个缓冲区将其地址存放到目的寄存器edi中xor edx,edxcld ;将0标志位清零,表示传递数据的时候地址递增, std命令则相反。_LoopBegin: ;一个标志 ,为了方便or ecx,ecx;或运算 其实就是ecx的值jz _WriteLinelodsb ;把esi寄存器中的内容从头开始依次放到al中,与stosb对应,stosb将al的内容依次放到edi中dec ecxcmp al,0dhjz _LoopBegincmp al,0ahjz _LineEndstosb;stosb将al的内容依次放到edi中,与lodsb对应inc edxcmp edx,sizeof @szBuffer-2 ;这个子程序处理的是一行文本而且这一行文本就放在缓冲区@szBuffer中,一 行文本最后就是0dh, 0ah,回车加换行,正好两个字节,如果处理的字节数edx大于等于缓冲区总字节数减去2的值,那么表示这一行的文本已经处理完了。jae _WriteLine ;大于等于则跳转jmp _LoopBegin_LineEnd:mov ax,0a0dhstosw;同stosb指令一个属性,只不过stosw是将ax中的内容放到edi中,与 lodsw对应inc edx ;这里讲edx计数器连续自加两次,原因就是stosw将两个字节(0dh, 0ah)读入到了edi中,处理了 两个字节inc edx_WriteLine:push ecx.if edxinvoke WriteFile,_hFile,addr @szBuffer,edx,addr @dwBytesWrite,NULL.endif lea edi,@szBuffer ;上面代码中已经将@szBuffer的地址传递给edi在这里再传一次还有必要么?经过我的测试发现,确实需要再传一 次,不然的话程序会出错退出xor edx,edxpop ecxor ecx,ecxjnz _LoopBeginret_FormatText endp

关于上面子程序的介绍应该已经很清楚了。

下面来看一下另一个问题:

以前也遇见过这个问题记不清楚了也没有解决,今天在这个程序中也用到了这个指令,如下一段代码所示:

.whileTRUEleaesi,@szReadBufferinvoke ReadFile,@hFile,esi,sizeof @szReadBuffer,addr @dwBytesRead,0.break .if ! @dwBytesRead ;这一行invoke _FormatText,esi,@dwBytesRead,@hFileNew.endw

如上面标注的一行 .break .if [条件] 这个语句

具体的意思就是:如果满足.if 中的条件则终止循环,跳出循环执行下面的语句。

与值对关的还有.continue .if [条件] 如果满足条件则结束当前语句,从新循环。

说完了这两个问题,下面来详细看一下程序实现代码:

.386.model flat, stdcalloption casemap :noneincludewindows.incincludeuser32.incincludelib user32.libincludekernel32.incincludelib kernel32.libincludecomdlg32.incincludelib comdlg32.libIDI_ICON1 equ 102IDD_DIALOG1equ 103IDC_BROWSE equ 40000IDC_FILE equ 40001.data?hInstance dd ?hWinMain dd ?szFileName db MAX_PATH dup (?).constszFileExt db '文本文件',0,'*.txt',0,0szNewFile db '.new.txt',0szErrOpenFile db '无法打开源文件!',0szErrCreateFile db '无法创建新的文本文件!',0szSuccess db '文件转换成功,新的文本文件保存为',0dh,0ah,'%s',0szSuccessCapdb '提示'.code_FormatTextproc uses esi _lpData,_dwSize,_hFileLOCAL@szBuffer[128]:byte,@dwBytesWritemov esi,_lpDatamov ecx,_dwSizelea edi,@szBufferxor edx,edxcld_LoopBegin:or ecx,ecxjz _WriteLinelodsbdec ecxcmp al,0dhjz _LoopBegincmp al,0ahjz _LineEndstosbinc edxcmp edx,sizeof @szBuffer-2jae _WriteLinejmp _LoopBegin_LineEnd:mov ax,0a0dhstosw inc edxinc edx_WriteLine:push ecx.if edxinvoke WriteFile,_hFile,addr @szBuffer,edx,addr @dwBytesWrite,NULL.endif lea edi,@szBuffer ;上面代码中已经将@szBuffer的地址传递给edi在这里再传一次还有必要么?xor edx,edxpop ecxor ecx,ecxjnz _LoopBeginret_FormatText endp_ProcFile procLOCAL@hFile,@hFileNew,@dwBytesReadLOCAL@szNewFile[MAX_PATH]:byteLOCAL@szReadBuffer[512]:byteinvokeCreateFile,addr szFileName,GENERIC_READ,FILE_SHARE_READ,0,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0;打开.if eax == INVALID_HANDLE_VALUEinvoke MessageBox,hWinMain,addr szErrOpenFile,NULL,MB_OK or MB_ICONEXCLAMATIONret.endifmov @hFile,eaxinvokelstrcpy,addr @szNewFile,addr szFileNameinvokelstrcat,addr @szNewFile,addr szNewFileinvokeCreateFile,addr @szNewFile,GENERIC_WRITE,FILE_SHARE_READ,0,OPEN_ALWAYS,FILE_ATTRIBUTE_NORMAL,0 ;创建.if eax == INVALID_HANDLE_VALUEinvoke MessageBox,hWinMain,addr szErrCreateFile,NULL,MB_OK or MB_ICONEXCLAMATIONinvoke CloseHandle,@hFileret.endifmov @hFileNew,eaxxor eax,eaxmov @dwBytesRead,eax.whileTRUEleaesi,@szReadBufferinvoke ReadFile,@hFile,esi,sizeof @szReadBuffer,addr @dwBytesRead,0.break .if ! @dwBytesReadinvoke _FormatText,esi,@dwBytesRead,@hFileNew.endwinvokeCloseHandle,@hFileinvokeCloseHandle,@hFileNewinvokewsprintf,addr @szReadBuffer,addr szSuccess,addr @szNewFileinvokeMessageBox,hWinMain,addr @szReadBuffer,addr szSuccessCap,MB_OKret_ProcFile endp_ProcDlgMainproc uses ebx edi esi hWnd,wMsg,wParam,lParamLOCAL@stOpenFileName:OPENFILENAMEmov eax,wMsg.if eax == WM_CLOSEinvoke EndDialog,hWnd,NULL.elseif eax == WM_INITDIALOGpushhWndpophWinMaininvoke LoadIcon,hInstance,IDI_ICON1invoke SendMessage,hWnd,WM_SETICON,ICON_BIG,eaxinvoke SendDlgItemMessage,hWnd,IDC_FILE,EM_SETLIMITTEXT,MAX_PATH,0.elseif eax == WM_COMMANDmoveax,wParam.ifax == IDC_BROWSEinvoke RtlZeroMemory,addr @stOpenFileName,sizeof OPENFILENAMEmov@stOpenFileName.lStructSize,sizeof @stOpenFileNamemov@stOpenFileName.Flags,OFN_FILEMUSTEXIST or OFN_PATHMUSTEXISTpush hWinMainpop@stOpenFileName.hwndOwnermov@stOpenFileName.lpstrFilter,offset szFileExtmov@stOpenFileName.lpstrFile,offset szFileNamemov@stOpenFileName.nMaxFile,MAX_PATHinvoke GetOpenFileName,addr @stOpenFileName.ifeaxinvoke SetDlgItemText,hWnd,IDC_FILE,addr szFileName.endif.elseif ax == IDC_FILEinvoke GetDlgItemText,hWnd,IDC_FILE,addr szFileName,MAX_PATHmovebx,eaxinvoke GetDlgItem,hWnd,IDOKinvoke EnableWindow,eax,ebx.elseif ax == IDOKcall _ProcFile.endif.elsemoveax,FALSEret.endif mov eax,TRUEret_ProcDlgMain endpstart:invoke GetModuleHandle,NULLmov hInstance,eaxinvoke DialogBoxParam,hInstance,IDD_DIALOG1,NULL,offset _ProcDlgMain,NULLinvoke ExitProcess,NULLend start

这次程序中使用的API函数和一些结构在以前的文章中都做过总结,没有出现新的内容,不在赘述,有某些不熟悉的,请查看以前的文章中的API函数和结构的信息的 详细描述。

本次程序分析到此结束。

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。