当前位置: 首页 > 编程语言 > 汇编语言 > 正文

汇编教程:汇编语言编程实例

时间:2008-12-27 本站收集整理

汇编语言编程实例一这一章,我们要把我们已学的知识集合起来。具体来讲,我们来写一个使用ODBC APIs的程序.为简单起见,这个程序中我使用Microsoft的Access数据库(Microsoft Access 97) .

注意:如果你使用的windows.inc 是1.18及其以下版本,在开始编译之前要修改其中的一个小bug.在windows.inc中查找 "SQL_NULL_HANDLE",将得到下面这行:

SQL_NULL_HANDLE equ 0L

将0后面的"L"删除,象这样:

SQL_NULL_HANDLE equ 0

这个程序是一个基于对话框的程序,有一个简单的菜单.当用户选择"connect"时,它将试图连接test.mdb数据库,如果连接成功,将显示由ODBC驱动程序返回的完整连接字符串.接下来,用户可选择"View All Records"命令,程序会使用listview control来显示数据库中的所有数据.用户还可以选择"Query"命令来查询特定的记录.例子程序将会显示一个小对话框提示用户输入想找的人名.当用户按下OK钮或回车键,程序将执行一个查询来查找符合条件的记录.当用户完成对数据库的操作时,可以选择"disconnect"命令与数据库断开连接.

现在看一下源程序:

.386
.model flat,stdcall
include \masm32\include\windows.inc
include \masm32\include\kernel32.inc
include \masm32\include\odbc32.inc
include \masm32\include\comctl32.inc
include \masm32\include\user32.inc
includelib \masm32\lib\odbc32.lib
includelib \masm32\lib\comctl32.lib
includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\user32.lib
IDD_MAINDLG equ 101
IDR_MAINMENU equ 102
IDC_DATALIST equ 1000
IDM_CONNECT equ 40001
IDM_DISCONNECT equ 40002
IDM_QUERY equ 40003
IDC_NAME equ 1000
IDC_OK equ 1001
IDC_CANCEL equ 1002
IDM_CUSTOMQUERY equ 40004
IDD_QUERYDLG equ 102
DlgProc proto hDlg:DWORD, uMsg:DWORD, wParam:DWORD, lParam:DWORD
QueryProc proto hDlg:DWORD, uMsg:DWORD, wParam:DWORD, lParam:DWORD
SwitchMenuState proto :DWORD
ODBCConnect proto :DWORD
ODBCDisconnect proto :DWORD
RunQuery proto :DWORD
.data?
hInstance dd ?
hEnv dd ?
hConn dd ?
hStmt dd ?
Conn db 256 dup(?)
StrLen dd ?
hMenu dd ? ; 主菜单句柄
hList dd ? ; listview control句柄
TheName db 26 dup(?)
TheSurname db 26 dup(?)
TelNo db 21 dup(?)
NameLength dd ?
SurnameLength dd ?
TelNoLength dd ?
SearchName db 26 dup(?)
ProgPath db 256 dup(?)
ConnectString db 1024 dup(?)
.data
SQLStatement db "select * from main",0
WhereStatement db " where name=?",0
strConnect db "DRIVER={Microsoft Access Driver (*.mdb)};DBQ=",0
DBName db "test.mdb",0
ConnectCaption db "Complete Connection String",0
Disconnect db "Disconnect successful",0
AppName db "ODBC Test",0
AllocEnvFail db "Environment handle allocation failed",0
AllocConnFail db "Connection handle allocation failed",0
SetAttrFail db "Cannot set desired ODBC version",0
NoData db "You must type the name in the edit box",0
ExecuteFail db "Execution of SQL statement failed",0
ConnFail db "Connection attempt failed",0
AllocStmtFail db "Statement handle allocation failed",0
Heading1 db "Name",0
Heading2 db "Surname",0
Heading3 db "Telephone No.",0
.code
start:
invoke GetModuleHandle, NULL
mov hInstance,eax
call GetProgramPath
invoke DialogBoxParam, hInstance, IDD_MAINDLG,0,addr DlgProc,0
invoke ExitProcess,eax
invoke InitCommonControls
DlgProc proc hDlg:DWORD, uMsg:DWORD, wParam:DWORD, lParam:DWORD
.if uMsg==WM_INITDIALOG
invoke GetMenu, hDlg
mov hMenu,eax
invoke GetDlgItem, hDlg, IDC_DATALIST
mov hList,eax
call InsertColumn
.elseif uMsg==WM_CLOSE
invoke GetMenuState, hMenu, IDM_CONNECT,MF_BYCOMMAND
.if eax==MF_GRAYED
invoke ODBCDisconnect, hDlg
.endif
invoke EndDialog,hDlg, 0
.elseif uMsg==WM_COMMAND
.if lParam==0
mov eax,wParam
.if ax==IDM_CONNECT
invoke ODBCConnect,hDlg
.elseif ax==IDM_DISCONNECT
invoke ODBCDisconnect,hDlg
.elseif ax==IDM_QUERY
invoke RunQuery,hDlg
.elseif ax==IDM_CUSTOMQUERY
invoke DialogBoxParam, hInstance, IDD_QUERYDLG,hDlg, addr QueryProc, 0
.endif
.endif
.else
mov eax,FALSE
ret
.endif
mov eax,TRUE
ret
DlgProc endp
GetProgramPath proc
invoke GetModuleFileName, NULL,addr ProgPath,sizeof ProgPath
std
mov edi,offset ProgPath
add edi,sizeof ProgPath-1
mov al,"\"
mov ecx,sizeof ProgPath
repne scasb
cld
mov byte ptr [edi+2],0
ret
GetProgramPath endp
SwitchMenuState proc Flag:DWORD
.if Flag==TRUE
invoke EnableMenuItem, hMenu, IDM_CONNECT, MF_GRAYED
invoke EnableMenuItem, hMenu, IDM_DISCONNECT, MF_ENABLED
invoke EnableMenuItem, hMenu, IDM_QUERY, MF_ENABLED
invoke EnableMenuItem, hMenu, IDM_CUSTOMQUERY, MF_ENABLED
.else
invoke EnableMenuItem, hMenu, IDM_CONNECT, MF_ENABLED
invoke EnableMenuItem, hMenu, IDM_DISCONNECT, MF_GRAYED
invoke EnableMenuItem, hMenu, IDM_QUERY, MF_GRAYED
invoke EnableMenuItem, hMenu, IDM_CUSTOMQUERY, MF_GRAYED
.endif
ret
SwitchMenuState endp
ODBCConnect proc hDlg:DWORD
invoke SQLAllocHandle, SQL_HANDLE_ENV, SQL_NULL_HANDLE, addr hEnv
.if ax==SQL_SUCCESS || ax==SQL_SUCCESS_WITH_INFO
invoke SQLSetEnvAttr, hEnv,SQL_ATTR_ODBC_VERSION, SQL_OV_ODBC3,0
.if ax==SQL_SUCCESS || ax==SQL_SUCCESS_WITH_INFO
invoke SQLAllocHandle, SQL_HANDLE_DBC, hEnv, addr hConn
.if ax==SQL_SUCCESS || ax==SQL_SUCCESS_WITH_INFO
invoke lstrcpy,addr ConnectString,addr strConnect
invoke lstrcat,addr ConnectString, addr ProgPath
invoke lstrcat, addr ConnectString,addr DBName
invoke SQLDriverConnect, hConn, hDlg, addr ConnectString, sizeof ConnectString, addr Conn, sizeof Conn,addr StrLen, SQL_DRIVER_COMPLETE
.if ax==SQL_SUCCESS || ax==SQL_SUCCESS_WITH_INFO
invoke SwitchMenuState,TRUE
invoke MessageBox,hDlg, addr Conn,addr ConnectCaption,MB_OK+MB_ICONINFORMATION
.else
invoke SQLFreeHandle, SQL_HANDLE_DBC, hConn
invoke SQLFreeHandle, SQL_HANDLE_ENV, hEnv
invoke MessageBox, hDlg, addr ConnFail, addr AppName, MB_OK+MB_ICONERROR
.endif
.else
invoke SQLFreeHandle, SQL_HANDLE_ENV, hEnv
invoke MessageBox, hDlg, addr AllocConnFail, addr AppName, MB_OK+MB_ICONERROR
.endif
.else
invoke SQLFreeHandle, SQL_HANDLE_ENV, hEnv
invoke MessageBox, hDlg, addr SetAttrFail, addr AppName, MB_OK+MB_ICONERROR
.endif
.else
invoke MessageBox, hDlg, addr AllocEnvFail, addr AppName, MB_OK+MB_ICONERROR
.endif
ret
ODBCConnect endp
ODBCDisconnect proc hDlg:DWORD
invoke SQLDisconnect, hConn
invoke SQLFreeHandle, SQL_HANDLE_DBC, hConn
invoke SQLFreeHandle, SQL_HANDLE_ENV, hEnv
invoke SwitchMenuState, FALSE
invoke ShowWindow,hList, SW_HIDE
invoke MessageBox,hDlg,addr Disconnect, addr AppName,MB_OK+MB_ICONINFORMATION
ret
ODBCDisconnect endp
InsertColumn proc
LOCAL lvc:LV_COLUMN
mov lvc.imask,LVCF_TEXT+LVCF_WIDTH
mov lvc.pszText,offset Heading1
mov lvc.lx,150
invoke SendMessage,hList, LVM_INSERTCOLUMN,0,addr lvc
mov lvc.pszText,offset Heading2
invoke SendMessage,hList, LVM_INSERTCOLUMN, 1 ,addr lvc
mov lvc.pszText,offset Heading3
invoke SendMessage,hList, LVM_INSERTCOLUMN, 3 ,addr lvc
ret
InsertColumn endp
FillData proc
LOCAL lvi:LV_ITEM
LOCAL row:DWORD
invoke SQLBindCol, hStmt,1,SQL_C_CHAR, addr TheName, sizeof TheName,addr NameLength
invoke SQLBindCol, hStmt,2,SQL_C_CHAR, addr TheSurname, sizeof TheSurname,addr SurnameLength
invoke SQLBindCol, hStmt,3,SQL_C_CHAR, addr TelNo, sizeof TelNo,addr TelNoLength
mov row,0
.while TRUE
mov byte ptr ds:[TheName],0
mov byte ptr ds:[TheSurname],0
mov byte ptr ds:[TelNo],0
invoke SQLFetch, hStmt
.if ax==SQL_SUCCESS || ax==SQL_SUCCESS_WITH_INFO
mov lvi.imask,LVIF_TEXT+LVIF_PARAM
push row
pop lvi.iItem
mov lvi.iSubItem,0
mov lvi.pszText, offset TheName
push row
pop lvi.lParam
invoke SendMessage,hList, LVM_INSERTITEM,0, addr lvi
mov lvi.imask,LVIF_TEXT
inc lvi.iSubItem
mov lvi.pszText,offset TheSurname
invoke SendMessage,hList,LVM_SETITEM, 0,addr lvi
inc lvi.iSubItem
mov lvi.pszText,offset TelNo
invoke SendMessage,hList,LVM_SETITEM, 0,addr lvi
inc row
.else
.break
.endif
.endw
ret
FillData endp
RunQuery proc hDlg:DWORD
invoke ShowWindow, hList, SW_SHOW
invoke SendMessage, hList, LVM_DELETEALLITEMS,0,0
invoke SQLAllocHandle, SQL_HANDLE_STMT, hConn, addr hStmt
.if ax==SQL_SUCCESS || ax==SQL_SUCCESS_WITH_INFO
invoke SQLExecDirect, hStmt, addr SQLStatement, sizeof SQLStatement
.if ax==SQL_SUCCESS || ax==SQL_SUCCESS_WITH_INFO
invoke FillData
.else
invoke ShowWindow, hList, SW_HIDE
invoke MessageBox,hDlg,addr ExecuteFail, addr AppName, MB_OK+MB_ICONERROR
.endif
invoke SQLCloseCursor, hStmt
invoke SQLFreeHandle, SQL_HANDLE_STMT, hStmt
.else
invoke ShowWindow, hList, SW_HIDE
invoke MessageBox,hDlg,addr AllocStmtFail, addr AppName, MB_OK+MB_ICONERROR
.endif
ret
RunQuery endp
QueryProc proc hDlg:DWORD, uMsg:DWORD, wParam:DWORD, lParam:DWORD
.if uMsg==WM_CLOSE
invoke SQLFreeHandle, SQL_HANDLE_STMT, hStmt
invoke EndDialog, hDlg,0
.elseif uMsg==WM_INITDIALOG
invoke ShowWindow, hList, SW_SHOW
invoke SQLAllocHandle, SQL_HANDLE_STMT, hConn, addr hStmt
.if ax==SQL_SUCCESS || ax==SQL_SUCCESS_WITH_INFO
invoke lstrcpy, addr Conn, addr SQLStatement
invoke lstrcat, addr Conn, addr WhereStatement
invoke SQLBindParameter,hStmt, 1, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR,25,0, addr SearchName,25,addr StrLen
invoke SQLPrepare, hStmt, addr Conn, sizeof Conn
.else
invoke ShowWindow, hList, SW_HIDE
invoke MessageBox,hDlg,addr AllocStmtFail, addr AppName, MB_OK+MB_ICONERROR
invoke EndDialog, hDlg,0
.endif
.elseif uMsg==WM_COMMAND
mov eax, wParam
shr eax,16
.if ax==BN_CLICKED
mov eax,wParam
.if ax==IDC_OK
invoke GetDlgItemText, hDlg, IDC_NAME, addr SearchName, 25
.if ax==0
invoke MessageBox, hDlg,addr NoData, addr AppName, MB_OK+MB_ICONERROR
invoke GetDlgItem, hDlg, IDC_NAME
invoke SetFocus, eax
.else
invoke lstrlen,addr SearchName
mov StrLen,eax
invoke SendMessage, hList, LVM_DELETEALLITEMS,0,0
invoke SQLExecute, hStmt
invoke FillData
invoke SQLCloseCursor, hStmt
.endif
.else
invoke SQLFreeHandle, SQL_HANDLE_STMT, hStmt
invoke EndDialog, hDlg,0
.endif
.endif
.else
mov eax,FALSE
ret
.endif
mov eax,TRUE
ret
QueryProc endp
end start