首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 其他教程 > 操作系统 >

win32汇编学习的一些撮要

2012-06-30 
win32汇编学习的一些摘要sizeof 变量名,数据类型或数据结构lengthof?变量名、数据类型或数据结构名sizeof

win32汇编学习的一些摘要

sizeof 变量名,数据类型或数据结构
lengthof?变量名、数据类型或数据结构名

sizeof 伪指令可以取得变量、数据类型或数据结构以字节为单位的长度,lengthof可以取得变量中数据的项数


????????????????窗口风格的预定义
预定义值???????????????????????含义
WS_OVERLAPPED????????????????????普通的重叠式窗口
WS_POPUP???????????????????????弹出式窗口(没有标题栏)
WS_CHILD???????????????????????子窗口
WS_MINIMINZE?????????????????????初始状态是最小化
WS_VISIBLE???????????????????????初始状态是可见的
WS_DISABLED??????????????????????初始状态是被禁止的
WS_MAXIMIZE??????????????????????初始状态是最大化的
WS_BORDER??????????????????????单线条边框
WS_DLGFRAME?????????????????????对话框类型的边框
WS_VSCROLL??????????????????????带垂直滚动条
WS_HSCROLL??????????????????????带水平滚动条
WS_SYSMENU??????????????????????带系统菜单(即带标题栏左上角的图标)
WS_THICKFRAME?????????????????????可以拖动调整大小的边框
WS_MINIMIZEBOX????????????????????有最小化按钮
WS_MAXIMIZEBOX????????????????????有最大化按钮

为了容易理解,Window也为一些定义取了一些别名,同时,由于窗口的风格往往是几种风格的组合,所以Window
也预定义了一些组合值,如下:
?????等效的窗口风格预定义值
预定义值????????????等效值
WS_CHILDWINDOW??????WS_CHILD
WS_TILED???????????WS_OVERLAPPED
WS_ICONIC??????????WS_MINIMIZE
WS_SIZEBOX?????????WS_THICKFRAME
WS_OVERLAPPEDWINDOW???WS_OVERLAPPED or WS_CAPTION or? WS_THICKFRAME or WS_MINIMIZEBOX ?or?WS_MAXIMIZEBOX
WS_TILEDWINDOW???????WS_OVERLAPPEDWINDOW
WS_POPUPWINDOW??????WS_POPUP or? WS_BORDER ?or? ?WS_SYSMENU

Win32窗口风格的一些扩展,它们是一些以WS_EX_开头的预义值,主要定义了一些特殊的风格,如下:
预定义值???????????????????含义
WS_EX_TOPMOST?????????????总在顶层的窗口
WS_EX_ACCEPTFILES????????????允许窗口进行鼠标拖放操作
WS_EX_TOOLWINDOW?? ?????????工具窗口(很窄的标题栏)
WS_EX_WINDOWEDGE???????????立体感的边框
WS_EX_CLIENTDGE?????????????客户区立体边框
WS_EX_OVERLAPPEDWINDOW????????WS_EX_WINDOWEDGE or?WS_EX_CLIENTEDGE
WS_EX_PALETTEWINDOW??????????WS_EX_WINDOWEDGE ?or?WS_EX_TOOLWINDOW or WS_EX_TOPMOST

???????

调用CreateWindowEx时窗口过程收到的消息
----------------------------------
消息发生?????????????说明
------------------------------------------
WM_GETMINMAXINFO?????获取窗口大小,以便初始化
WM_NCCREATE????????非客户区开始建立
WM_NCCALCSIZE????????非客户区大小
WM_CREATE??????????窗口建立
-----------------------------------

?

调用ShowWindow时窗口过程收到的消息
-------------------------------------------------------
消息发生???????????????????说明
-------------------------------------------------------
WM_SHOWWINDOW????????????显示窗口
WM_WINDOWPOSCHANGING????????窗口位置准备改变
WM_ACTIVATEAPP????????????窗口准备激活
WM_NCACTIVATE?????????????激活状态改变
WM_GETTEXT??????????????取窗口名称(显示标题栏目)
WM_ACTIVATE??????????????窗口准备激活
WM_SETFOCUS??????????????窗口获取焦点
WM_ERASEBGND?????????????需要擦除背景
WM_WINDOWPOSCHEANGED????????窗口位置已经改变
WM_SIZE??????????????????????????????????????????????????????????????????????? 窗口大小已经改变
WM_MOVE????????????????窗口位置已经移动
--------------------------------------------------


调用DestroyWindow时窗口过程收到消息
---------------------------------------------
消息发生???????????????? 说明
-----------------------------------------------------------------------
WM_NCACTIVATE????????????窗口激活状态
WM_ACTIVATE?????????????窗口准备非激活
WM_ACTIVATEAPP???????????窗口准备非激活
WM_KILLFOCUS????????????失去焦点
WM_DESTROY?????????????窗口即将被摧毁
WM_NCDESTROY????????????窗口的非客户区及所有子窗口已经被摧毁
-----------------------------------------------------------

DefWindowProc对一些消息的默认处理方式
-----------------------------------------------------------
消息?????????????????DefWindowProc的处理方式
---------------------------------------------------------
WM_PAINT??????????????发送WM_ERASEBKGND消息来擦除背景
WM_ERASEBKGND??????????用窗口类结构中的hrBackground刷子来绘画窗口背景
WM_CLOSE?????????????调用DestroyWindow来摧毁窗口
WM_NCLBUTTONDBLCLK???????这是非客户区(如标题栏)鼠标双击消息,DefWindowProc测试鼠标的位置,然后再采
??????????????????取相应的措施,如标题栏双击将最大化和恢复窗
WM_NCLBUTTONUP??????????这是非客户区鼠标释放消息,同样,DefWindowProc测试的位置然后再采用相相应的
??????????????????措施,如鼠标在"关闭"按钮的位置释放将导致发送WM_CLOSE消息
WM_NCPAINT????????????非客户区绘制消息,DefWindowProc将绘制边框和客户区
--------------------------------------------------------------------------

窗口建立的过程
GetModuleHandle---------->RtlZeroMemory---->LoadCursor------>RegisterClassEx----->CreateWindowEx---->ShowWindow--->UpdateWindow


GetModuleHandle ;//得到窗口句柄
LoadMenu//得到窗口的菜单句柄
LoadAccelerator;//得到右键句柄


得到鼠标位置

GetCursorPos,addr @stPos;其中@stPos是 一个POINT类型的变量


不同应用程序之间的窗口是可以发送消息的,通过SendMessage或者PostMessage函数,用法如下:
??invoke? SendMessage?,hWnd,Msg,wParam,lParam
??invoke?PostMessage,hWnd,Msg,wParam,lParam


如果要改变窗口的光标,正确的办法是用SetClassLong函数改变窗口类的属性,这个函数的使用方法如下:
????invoke SetClassLong,hWnd,nIndex,dwNewLong
这个函数用来改变窗口的属性,所以可以改变类中的光标设定,hWnd用来设定一个这个类建立的某个窗口句柄,nIndex参数指定要改变
窗口类的哪个属性,可以指定为GCL_HBRBACKGROUND,GCL_HCURSOR,GCL_HICON,GCL_HMODULE,GCL_MENUNAME,GCL_STYLE或GCL_WNDPROC等,
它们分别表示 要改变的窗口类的背景色、光标、图标、Hinstance,菜单、风格或窗口过程地址,读者可以用这个函数来改变一个窗口
类的几乎所有属性,程序中通过这个函数将窗口的光标在不同的光标句柄之间切换:
???invoke SetClassLong,hWnd,GCL_HCUROSR,hCur1或hCur2
在资源脚本中定义的是控件的ID,当这些子窗口控件被创建以后同样会有一个窗口句柄,但既然它们不是由我们自己创建的,那么怎么知道它们的窗口
句柄呢?有一个函数可以从ID中获取句柄:
?invoke?GetDlgItem,hDlg,dwIDDlgItem
?mov??hDlgItem,eax
?函数的输入参数是对话框和ID值,返回值是子窗口句柄:返过来,有两种方法可以从子窗口句柄获取ID:
?(1)?invoke?GetDlgCtrlID,hWndCtrl;输入子窗口句柄,返回值是控件ID
?(2)?invoke?GetWindoLong,hWndCtrl,GWL_ID
? 当需要向控件发送消息的时候,当然可以先用GetDlgItem获取子窗口句柄再用SendMessage函数,但有一个
? 更为简便:
? ??invoke?SendDlgItemMessage,hDlg,dwIDDlgItem,Msg,wParam,lParam
? 这个函数可以直接向控件发送消息,只需要在参数中指定对话框句柄和子窗口ID(注意,并没有PostDlgItemMessage这样的函数!)。
?
?
?单选钮和复选框
?单选钮和复选框都是基于Button类的,只不过它们的窗口分别是BS_RADIOBUTTON和BS_CHECKBOX.
?既然它们是特殊“按钮”,所以和它们有关的函数都带有“Button"一词,查看一个单选钮或复选框是否可以
?用下面的函数来检测:
?invoke?IsDlgButtonChecked,hDlg,nIDButton
?函数的返回值可能是BST_CHECKED(选中状态),BST_INDETERMINATE(3态复选框的灰化状态)或BST_UNCHECKED(未选中状态)。也
?可以用向子窗口控件发送BM_GETCHECK消息的方法来检测,返回值和上面的函数是一样的。
?如果想设置单选按钮或复选框的状态,可以使用下面蝗语句:
?invoke?CheckDlgButton,hDlg,nIDButton,uCheck
?参数uCheck用BST_CHECKED,BST_INDETERMINATE或BST_UNCHECKED来表示需要设置的状态,含义同上。向控件发送BM_SETCHECK消息
?也可以取得同样的效果,这时消息的wParam中放置需要的状态。
?复选框是不互斥的,所以 可随意主设置状态。而对于BS_RADIOBUTTON风格的单选按钮来说,并不是把某个按钮设置为选中以后,如果不是手动把同组的其他按钮全部
?改为非选 中状态(逐个地调用 CheckDlgButton),就会看到同是圾两个单选钮是选 中的。但把同组的所有单选钮逐个地设置显得有点麻烦,所以针对单选钮有个专用函数:
?invoke?CheckRadioButton,hDlg,nIDFirstButton,nIDLastButton,nIDCheckedButton
?
?
?
?文本编辑控件
?文本编辑器是基于Edit类的控件,可以用缩写EDITTEXT定义,读者可以在文本编辑控件中输入并编辑文本。每当用户在文本编辑控件中输入一个字符的时候,控件就会向对话框过
?程发送一个WM_COMMAND消息,所以在例子程序中,当在自定义文字的编辑框中每输入一个字,标题栏文字就会马上改变以。
?当获取编辑框中的文本有多种方法,可以用GetWindowText,也可以用发送WM_GETTEXT消息的办法,要设置文本,同样可以用SetWindowText或发送WM_SETTEXT,但最简便的办法还是
?使用下的函数:
?invoke GetDlgItemText,hDlg,nIDDlgItem,ipString,nMaxCount;取文本
?invoke SetDlgItemText,hDlg,nIDDlgItem,lpString;设置文本
?在实际使用中,经常要在文本编辑控件中输入输出值型参数,将文本转换为数值比较麻烦,把数值转换为文本也要经过一个wsprintf调用,为了简化 操作,Windows提供了两个
?函数来处理这个问题:
?invoke?GetDlgItemInt,hDlg,nIDDlgItem,uValue,bSigned;取控件中的数值
?invoke?SetDlgItemInt,hDlg,nIDDlgItem,lpTranslated,bSigned;设置控件中的数值
?下面的例子将IDC_EDIT的输入最大长度定为10个字符:
?invoke?SendDlgItemMessage,hDlg,IDC_EDIT,EM_LIMITTEXT,10,NULL
?invoke?SendDlgItemMessage,hDlg,IDC_EDIT,EM_SETREADONLY,TRUE,NULL;只读
?invoke?SendDlgItemMessage,hDlg,IDC_EDIT,EM_SETREADONLY,FALSE,NULL;可写
?
?
?滚动条
?和其他子窗口控件发送WM_COMMAND消息不同,水平滚动条向对话框窗口发送WM_HSCROLL消息,而垂直滚动条则发送WM_VSCROLL消息,所以针动
?对两种方式的滚动条分别处理不同的 消息:
?WM_xSCROLL消息的参数如下所示:
?wParam的低16位==nScrollCode;动作码
?wParam的高16位==?nPos;滚动条当前位置
?lParam==hwndScrollBar;滚动条控件的窗口句柄
?
?
?
?组合框
?3种类型的组合框:
?CBS_SIMPLE,CBS_DROPDOWN,CBS_DROPDOWNLIST
?组合框 中还有几种常用的、可以附加的风格:
?CBS_AUTOSCROLL???输入过长的文本时输入框自动卷动
?CBS_LOWERCASE???自动将所有的文本转换成小写
?CBS_SORT??????自动将插入的文本项排序
?CBS_UPPERCASE????自动将所有的文本转换成大写
?
??????????组合框消息
消息?????????Wparam?????????lParam???????????说明
CB_ADDSTRING??????0???????????字符串地址???????把一个字符串添加到列表中
CB_INSERTSTRING???位置索引?????????字符串地址???????把一个字符插入到列表中
CB_FINDSTRING????开始查找的位置索引????查找的字符串??????在列表中查找以lParam字符中开头的项,的巧劲则返回
???????????????????????????????????位置索引,未找到返回CB_ERR
CB_FINDSTRINGEXACT??位置索引?????????查找的字符串??????精确查找字符串
CB_DELTESTRING????位置索引??????????0???????????删除一个列表项
CB_RESTECONTEXT?????0????????????0???????????删除所有了列表项
CB_GETLBTEXT?????位置索引?????????缓冲区地址???????获取指定列表项的字符串,缓冲必须足够大
CB_GETLBTEXTLEN???位置索引??????????0???????????获取指定列表项的字符串长度
CB_GETCOUNT????0??????????????0???????????获取列表项的总数
CB_SETCURSEL?????位置索引??????????0???????????选中一个列表项,并将列表项中的文字拷贝到编辑控件中
CB_SELECTSTRING???开始查找的位置索引????字符串地址???????查找以lParam指定的字符中开始的列表项,如果找到则选中
???????????????????????????????????中它将字符串拷贝到编辑框 中
CB_GETCURSET????0??????????????0???????????获取当前选中位置索引,没有选中的项目则返回CB_ERR
CB_SHOWDROPDOWN??状态???????????0???????????打开(状态为TRUE)或收起(状为FALSE)下拉列表
CB_GETDROPEDSTATE??0??????????????0???????????检测列表的当前下拉状态,返回TRUE表示拉下,FALSE表示收起

当用户在组合框中进行选 择操作时,Windows向对话框过程发送WM_COMMAND消息,消息中的WParam参数的低16位是组合框,高16位是通知码,用来表示
用户的操作,通知码的定义:
???????????用户操作组合框后的通知码
????通知码????????????说明
?CBN_SELCHANGE???????用户将要选择一个项目(鼠标移动到了这个项目上)
?CBN_CLOSEUP????????下拉列表关闭(可能是选 择完成也可能是取消选择)
?CBN_SELENDOK???????用户完成选择
?CBN_SELENDCANCEL?????用户取消选择(鼠标移动到了某个项目上,但并没有按下而是点击了其控件,或按动了ESC键)
?CBN_DBLCLK????????在CBS_SIMPLE的组合框中双击了一个列表项
?CBN_DROPDOWN??????用户打开了下拉框(按动了编辑框边的下拉按钮)
?
?
?当列表框是LBS_NOTIFY风格的时候,用户有所动作时列表框 会向父窗口发送WM_COMMAND消息,同时在wParam的高16位中指定
?通知码,列表框的通知码种类很少,基本上就是以下几种:
?.LBN_DBLCLK??????用户双击了一个项目
?.LBN_ERRSPACE?????插入项目时无法申请到足够的内在
?.LBN_KILLFOCUS?????输入焦点被切换到其他控件中列表丢失了焦点
?.LBN_SELCANCEL?????用户撤销了一个选择
?.LBN_SELCHANGE?????选定状态改变
?.LBN_SETFOCUS?????列表框得到了焦点
?列表框通知父窗口是通过发送WM_COMMAND消息,而程序控制列表框的时候是通过向列表框发送消息来完成的,常用的列表框消息如下:
?消息??????????wParam??????lParam???????????说明
?LB_ADDSTRING?????0?????????字符串地址???????添加一个项目,返回加入后的索引
?LB_DELETESTRING?????位置索引??????0???????????删除一个项目,返回剩余的项数
?LB_FINDSTRING?????开始索引??????字符串地址??????查找以字符串开头的项目,找到则返回位置索引,未找到则返回LB_ERR
?LB_FINDSTRNGEXACT???开始索引??????字符串地址??????精确查找一个项目,返回值同上
?LB_GETANCHORINDEX????0?????????0???????????返回多选列表框多选时的起始位置
?LB_GETACRETINDEX?????0?????????0???????????多选框中的当前焦点项目焦点位置
?LB_GETCOUNT???????0?????????0???????????返回列表框中的项目总数
?LB_GETCURSETL??????0?????????0???????????返回列表框中当前选中的项目
?LB_GETSEL????????位置索引?????0???????????检测指定项目的选中状态,返回非0为选中,返回0为未选 中
?LB_GETSELCOUNT?????0?????????0???????????返回列表框中选中项目的总数
?LB_GETSELLITEMS??????最大项数????缓冲区地址???????返回多选列表框的选中项目索引列表到缓冲区中
?LB_GETTEXT????????位置索引????缓冲区地址???????返回某个项目的字符串
?LB_GETTEXTLEN??????位置索引?????0???????????返回某个项目的字符串长度
?LB_GETTOPINDEX??????0?????????0???????????返回当前可见的第一个项目位置
?LB_INSERTSTRING?????插入位置????字符串地址???????在指定位置插入一个项目
?LB_RESETCONTENT?????0?????????0???????????删除所有项目
?LB_SELECTSTRING??????开始位置????字符串地址???????将以指定字符串开头的项目选 中
?LB_SELITEMRANGE?????选择状态????范围??????????在多选框中将一个范围选中或清除
?LB_SETCURSEL???????位置索引?????0???????????在单选框中选 择一个项目
?LB_SETSEL?????????选择状态????位置索引????????在多选框中将一个项目选中或清除
?LB_SETTOPINDEX??????位置索引?????0???????????滚动显示到指定的项目
?LB_DIR??????????属性??????文件通配符???????搜索目录并将符合文件通配符的文件名加入到列表框中
?在这些消息中LB_DIR 是个比较有趣的消息,它可以指定目录中的文件名自动列出来并加入到列表框中,如例子中用*.*将当前目录 的全冲毁文件名加到列表框中。LB_DIR
?消息中wParam参数可以指定的属性可以是以下值的组合:
?.DDL_ARCHIVE??????加入归档属性的文件
?.DDL_DIRECTORY?????加入目录
?.DDL_DRIVES???????加入驱动器名
?.DDL_HIDDEN??????包含隐含文件
?.DDL_READONLY?????包含只读文件
?.DDL_READWRITE?????包含可读写的文件
?.DDL_SYSTEM??????包含系统文件
?
?
?申请一个定时器使用SetTimer函数,函数的使用方法如下:
?invoke?SetTimer,hWnd,nIDEvent,uElapse,lpTimeFunc
?hWnd参数是WM_TIMER消息发往的窗口句柄;nIDEvent参数是一个用户指定的任意整数,用来标识 一个程序中的多个定时 器
?;uElapse是时间周期,以ms为单位,这个参数是必须指定的;lpTimerFunc是定时器过程。
?撤消定时器的函数是KillTimer,该函数的使用方法:
?invoke?KillTimer,hWnd,uIDEvent
?参数 hWnd,uIDEvent就是申请时用来的参数
?申请定时器的有两个方法:
?第一个:
?invoke?SetTimer,hWnd,ID_TIMER,250,NULL
?这时参数lpTimeFunc必须为NULL
?第二种:
?invoke?SetTimer,NULL,NULL,1000,addr _ProcTimer
?把返回的值保存下来,以便注销是使用。
?定时器过程如下定义:
?TimeProc?proc??hwnd,uMsg,idEvent,dwTime
?
?显示设备的颜色深度可以用以下函数获取:
???invoke??GetDeviceCaps,hDc,PLANES
???mov???ebx,dwPlanes
???invoke??GetDeviceCaps,hDc,BITSPIXEL
???mul???ebx
???mov???dwColorDepth,eax
???第一个函数调用返回DC的色彩平面数,第二函数调用返回每个像素的色彩位数,
颜色深度最后可以通过dwPlanes乘以dwBitsPixel得到.

Window也提供了其他一些坐标映射方法供程序员使用,可以用SetMap? Mode函数来为一个DC设置新的坐标映射方法:
???invoke??SetMapMode,hDc,iMapMode
???参数iMapMode可以取下面的值:

????????Windows中可用的坐标映射方式

映射方法???????????原点????????? 逻辑单位???????X正方向?????Y正方向
MM_TEXT(默认方式)???????左上???????像素?????????右????????下
MM_HIENGLISH?????????左上???????0.001英寸???????右???????????????????????????????? 上
MM_LOENGLISH?????????左上???????0.001英寸???????右???????? 上
MM_HIMETRIC?????????左上???????0.001毫米???????右???????? 上
MM_LOMETRIC?????????左上???????0.1毫米????????右???????? 上
MM_TWIPS???????????左上???????1/1440英寸???????右???????? 上
MM_ISOTROPIC?????????可变???????可变(x=y)??????可变???????可变
MM_ANISOTROPIC????????可变???????可变(x!=y)?????????????????????? 可变???????可变

最后两种映射方式提供了更灵活了选择,设置为这两种映射方式后,程序可以继续调用SetViewPortOrgEx,SetViewportExtEx和
SetWindowExtEx函数来自由设置坐标系的原点,罗辑单位和坐标的正方向等所有参数,在其他映射方式下的时候,不能使用这
3个设置函数,这时任何对它们的调用都会被忽略.


数据传递和对常量的操作指令

指令格式
?指令含义
?执行的操作
?
FLD src
?装入实数到st(0)
?st(0) <- src (mem32/mem64/mem80)
?
FILD src
?装入整数到st(0)
?st(0) <- src (mem16/mem32/mem64)
?
FBLD src?
?装入BCD数到st(0)
?st(0) <- src (mem80)
?
?
?
FLDZ
?将0.0装入st(0)
?st(0) <- 0.0
?
FLD1
?将1.0装入st(0)
?st(0) <- 1.0
?
FLDPI
?将pi装入st(0)
?st(0) <- ?(ie, pi)
?
FLDL2T
?将log2(10)装入st(0)
?st(0) <- log2(10)
?
FLDL2E
?将log2(e)装入st(0)
?st(0) <- log2(e)
?
FLDLG2
?将log10(2)装入st(0)
?st(0) <- log10(2)
?
FLDLN2
?将loge(2)装入st(0)
?st(0) <- loge(2)
?
?
?
FST dest
?保存实数st(0)到dest
?dest <- st(0) (mem32/mem64)
?
FSTP dest
??
?dest <- st(0) (mem32/mem64/mem80);然后再执行一次出栈操作
?
FIST dest
?将st(0)以整数保存到dest
?dest <- st(0) (mem32/mem64)
?
FISTP dest
??
?dest <- st(0) (mem16/mem32/mem64);然后再执行一次出栈操作
?
FBST dest
?将st(0)以BCD保存到dest
?dest <- st(0) (mem80)
?
FBSTP dest?
??
?dest<- st(0) (mem80);然后再执行一次出栈操作
?

2.比较指令

指令格式
?指令含义
?执行的操作
?
FCOM
?实数比较
?将标志位设置为 st(0) - st(1) 的结果标志位
?
FCOM op
?实数比较
?将标志位设置为 st(0) - op (mem32/mem64)的结果标志位
?
?
?
FICOM op
?和整数比较
?将Flags值设置为st(0)-op 的结果op (mem16/mem32)
?
FICOMP op
?和整数比较
?将st(0)和op比较 op(mem16/mem32)后;再执行一次出栈操作
?
?
?
FTST?
?零检测?
?将st(0)和0.0比较
?
FUCOM st(i)?
??
?比较st(0) 和st(i)????????????????? [486]
?
FUCOMP st(i)??????
??
?比较st(0) 和st(i),并且执行一次出栈操作
?
FUCOMPP st(i)????
??
?比较st(0) 和st(i),并且执行两次出栈操作
?
FXAM??
??
?Examine: Eyeball st(0) (set condition codes)
?

3.运算指令

指令格式
?指令含义
?执行的操作
?
加法
?
FADD
?加实数
?st(0) <-st(0) + st(1)
?
FADD src
??
?st(0) <-st(0) + src (mem32/mem64)
?
FADD st(i),st
??
?st(i) <- st(i) + st(0)
?
FADDP st(i),st?
??
?st(i) <- st(i) + st(0);然后执行一次出栈操作
?
FIADD src??
?加上一个整数
?st(0) <-st(0) + src (mem16/mem32)
?
减法
?
FSUB
?减去一个实数
?st(0) <- st(0) - st(1)
?
FSUB src
??
?st(0) <-st(0) - src (reg/mem)
?
FSUB st(i),st
??
?st(i) <-st(i) - st(0)
?
FSUBP st(i),st
??
?st(i) <-st(i) - st(0),然后执行一次出栈操作
?
FSUBR st(i),st
?用一个实数来减
?st(0) <- st(i) - st(0)
?
FSUBRP st(i),st
??
?st(0) <- st(i) - st(0),然后执行一次出栈操作
?
FISUB src
?减去一个整数
?st(0) <- st(0) - src (mem16/mem32)
?
FISUBR src
?用一个整数来减
?st(0) <- src - st(0) (mem16/mem32)
?
乘法
?
FMUL
?乘上一个实数
?st(0) <- st(0) * st(1)
?
FMUL st(i)
??
?st(0) <- st(0) * st(i)
?
FMUL st(i),st
??
?st(i) <- st(0) * st(i)
?
FMULP st(i),st
??
?st(i) <- st(0) * st(i),然后执行一次出栈操作
?
FIMUL src
?乘上一个整数
?st(0) <- st(0) * src (mem16/mem32)
?
FSQRT
?平方根
?st(0) <- sqrt st(0)
?
?
?
FSCALE
?2的st(0)次方
?ST(0) <- ST(0)*(2^ST(1))
?
FXTRACT
?Extract exponent:
?st(0) <-exponent of st(0); and gets pushed

st(0) <-significand of st(0)
?
?
?
FPREM?
?取余数
?st(0) <-st(0) MOD st(1)
?
FPREM1
?取余数(IEEE),同FPREM,但是使用IEEE标准[486]
?
?
??
??
?
FRNDINT?
?取整(四舍五入)
?st(0) <- INT( st(0) ); depends on RC flag
?
?
?
FABS
?求绝对值
?st(0) <- ABS( st(0) ); removes sign
?
FCHS
?改变符号位(求负数)
?st(0) <-st(0)
?
?
?
F2XM1
?计算(2 ^ x)-1
? st(0) <- (2 ^ st(0)) - 1
?
FYL2X??
?计算Y * log2(X)
?st(0)为Y;st(1)为X;将st(0)和st(1)变为st(0) * log2( st(1) )的值
?
?
?
FCOS
?余弦函数Cos
?st(0) <- COS( st(0) )
?
FPTAN
?正切函数tan
?st(0) <- TAN( st(0) )
?
FPATAN
?反正切函数arctan
?st(0) <- ATAN( st(0) )
?
FSIN
?正弦函数sin
?st(0) <- SIN( st(0) )
?
FSINCOS
?sincos函数
?st(0) <-SIN( st(0) ),并且压入st(1)

st(0) <- COS( st(0) )
?
?
??
??
?
FYL2XP1?
?计算Y * log2(X+1)
?st(0)为Y; st(1)为X; 将st(0)和st(1)变为st(0) * log2( st(1)+1 )的值
?
处理器控制指令
?
FINIT
?初始化FPU
??
?
FSTSW AX
?保存状态字的值到AX
?AX<- MSW
?
FSTSW dest
?保存状态字的值到dest
?dest<-MSW (mem16)
?
?
??
??
?
FLDCW src
?从src装入FPU的控制字
?FPU CW <-src (mem16)
?
FSTCW dest
?将FPU的控制字保存到dest
?dest<- FPU CW
?
?
??
??
?
FCLEX?
?清除异常
??
?
?
??
??
?
FSTENV dest
?保存环境到内存地址dest处 保存状态字、控制字、标志字和异常指针的值
?
FLDENV src
?从内存地址src处装入保存的环境
??
?
FSAVE dest
?保存FPU的状态到dest处 94字节
??
?
FRSTOR src
?从src处装入由FSAVE保存的FPU状态
??
?
?
??
??
?
FINCSTP
?增加FPU的栈指针值
?st(6) <-st(5); st(5) <-st(4),...,st(0) <-?
?
FDECSTP
?减少FPU的栈指针值
?st(0) <-st(1); st(1) <-st(2),...,st(7) <-?
?
?
??
??
?
FFREE st(i)
?标志寄存器st(i)未被使用
??
?
?
??
??
?
FNOP?
?空操作,等同CPU的nop
?st(0) <-st(0)
?
WAIT/FWAIT
?同步FPU与CPU:停止CPU的运行,直到FPU完成当前操作码
?
?
?
FXCH
?交换指令,交换st(0)和st(1)的值
?st(0) <-st(1)

st(1) <- st(0)

使用预定义的画笔和画刷
GetStockObject函数的用法是:
?invoke?GetStockObject,fnObject
?mov???hObject,eax
?fnObject参数是预定义的对象类型,可以是下面的取值:
?预定义值???????????????????说明
?BLACK_PEN?????????????????黑色画笔
?WHITE_PEN?????????????????白色画笔
?NULL_PEN??????????????????空画笔
?BLACK_BRUSH????????????????黑色画刷
?DKGRAY_BRUSH???????????????深灰色画刷
?GRAY_BRUSH?????????????????灰色画刷
?LTGRAY_BRUSH????????????????浅灰色画刷
?WHITE_BRUSH????????????????白色画刷
?HOLLOW_BRUSH或NULL_BRUSH????????空画刷
?ANSI_FIXED_FONT???????????????等宽系统字体
?ANSI_VAR_FONT????????????????不等宽系统字体
?DEFAULT_GUI_FONT(Win95)???????????默认系统字体(用于菜单、对话框等)
?OEM_FIXED_FONT???????????????OEM等宽字体
?SYSTEM_FONT????????????????默认系统字体(用于菜单、对话框等)
?DEFAULT_PALETTE??????????????默认图案
?用GetStockObject函数得到对象句柄以后,就可以用SelectObject函数将对象句柄设置到DC中。
?SelectObject函数可以指定一个DC当前使用的对象对应哪个对象句柄,称为’当前对象‘,当设置了一个当前
?对象的时候,以后和这种对象相关的函数都将使用当前对象,直到再次用SelectObject选择新的对象为止。
?
?使用自定义的画笔和画刷
?使用GetStockObject函数得到的对象是最"简单"的,如画笔只能是白色或黑色的宽度为1像素的实线,画刷只能是
?白色、黑色和有限的几种灰色色块。要想使用彩色的、多种多样风格的画笔和画刷,就必须用自定义的方法。
?创建自定义的画笔可以使用CreatePen,ExtCreatePen或CreatePenIndirect函数,CreatePen函数的使用方法如下:
???invoke?CreatePen,fnPenStyle,dwWidth,dwColor
???mov???hPen,eax
?创建自定义画刷可以使用的函数有:CreateSolidBrush,CreateHatchBrush,CreatePatternBrush和CreateBrushIndirect.
?CreateSolidBrush创建单色的画刷:
?invoke??CreateSolidBrush,dwColor
?mov???hBrush,eax
?要输入的参数是画刷的颜色。而CreateHatchBrush可以创建几种预定义图案的画刷:
?invoke??CreateHatchBrush,iHatchStyle,dwColor
?mov???hBrush,eax
?iHatch定义了不同的图案线条,这些图案线条实际上是以8*8位图重复铺组成,iHatchStyle的定义值可以是HS_BDIAGONAL,
?HS_CROSS,HS_DIAGCROSS,HS_FDIAGONAL,HS_HORIZONTAL和HS_VERTICAL这六种图案。
?如果这引动简单的图案不能满足使用要求,CreatePatternBrush是个很好的选择:
??invoke?CreatePatternBrush,hBitmap
??mov??hBrush,eax
??这个函数是用一个位图做画刷的图案,当要绘画的区域大于位图尺寸的时候,位图被重铺开。
??
??绘制像素点
??invoke??SetPixel,hDc,dwx,dwy,dwColor
??SetPixel函数在hDc的dwX,hwY位置以dwColor为颜色画上一个像素点,如果需要获取hDc中某个像素点当前的颜色值,那
??么可以使用GetPixel函数:
??invoke??GetPixel,hDc,dwX,dwY
??mov?dwColor,eax
??图形处理前最基本的步骤是获取像素,但也不应该用GetPixel函数来获取一大块的像素数据,理由是同样的。如查要
??分析整个区域的像素数据,最好的办法就是用GetDIBits函数将全部数据拷贝到内存中再过行处理。
??
??绘制线条
??如查要设置当前点的位置,可以使用MovToEx函数:
??invoke?MovToEx,hDC,dwX,dwY,lpPoint
??dwX,dwY指出了新的当前点的坐标,lpPoint指向一个空的POINT结构,用来返回原来的当前点位置,如果不需要的话,这个参数右以使用NULL.
?另一个函数也可以得到当前点的坐标:
?invoke??GetCurrentPositionEx,hDC,lpPoint
?如果要绘 制一条直线,然后用LineTo绘画到结束坐标。
?如果要绘制是相连的多条直线,可以使用Polyline或PolylineTo函数:
??invoke??PolylineTo,hDC,lpPoint,cPoints
??invoke??Polyline,hDC,lpPoint,cPoints
?lpPoint指向一个包含一系列POINT结构的缓冲区,由于POINT结构只有X和Y两个字段,所以缓冲区中的数据实际上是X1,Y1,X2,Y2,X3,Y3...,,cPoints参数
?指出了点的数目。
?画线函数的功能
??函数?????????????????????????????????说明
??LineTo(hDC,x,y)?????????????????????????从当前点到(x,y)
??PolyLineTo(hDC,lpPoint,5)????????????????????lpPoint指向存放(x1,y1)到(x5,y5)的缓存区,
????????????????????????????????函数画的线条从(xc,yc)到(x1,y1)到(x2,y2)...到(x5,y5),共
????????????????????????????????5条直线
??
??
??PolyLine(hDC,lpPoint,5)?????????????????????lpPoint指向存放(x1,y1)到x5,y5的缓存区,函数画的线条从(x1,y1)到(x2,y2)..
????????????????????????????????到(x5,y5),共4 条直线
????????????????????????????????
????????????????????????????????
??PloyBzierTo(hDC,lpPoint,3)???????????????????绘画的Bezier曲线的控制点为(xc,yc)和(x1,y1)和(x2,y2)和(x3,y3)
??
??
??PloyBzier(hDC,lpPoint,4)????????????????????绘画的Bezier曲线的控制点为(x1,y1)和(x2,y2)和(x3,y3)和(x4,y4)
??
??
??ArcTo(hDc,x1,y1,x2,y2,x3,y3,x4,y4)????????????????首先画(xc,yc)到起始点的直线,再画起始点到结束点的弧线
??
??
??Arc(hDc,x1,y1,x2,y2,x3,y3,x4,y4)?????????????????画起始点到结束点的弧线
??
??在默认情况下,圆弧由起始点沿着椭圆从逆时针方向画到结束点。不过绘画方向可以由SetArcDirection函数重新规定:
??invoke??SetArcDirection?,hDC,AD_COUNTERCLOCKWISE;逆时针方向
??invoke??SetArcDirection?,hDC,AD_CLOCKWISE;顺时针方向
??如果绘 画为虚线时,可以选择不连续部分的颜色:
??invoke??SetBkColor??,hDC,dwColor
??调用后,不连续的部分就将用dwColor指定的颜色绘画
??但是改变颜色也并不是惟一的选择,GDI允许这部分并不绘 画任何颜色,也就是可以是"透明"的,用下面的
??调用可以将模式在透明和非透明之间切换:
??invoke??SetBkModel,hDC,OPAQUE;非透明模式
??invoke??SetBkModel,hDC,TRANSPARENT;透明模式
??两种模式以及绘 画颜色不单影响虚线的空隙部分,同样也影响CreateHatchBrush函数创建的画刷,因为这种画刷使用几种
??由线条构成的图案,当用这种画刷填充一个区域的时候,线图案的空隙部分同样受SetBkColor函数和SetBkMode函数的影响。
??
??绘制边界框和填充区域
??绘制边界框和填充区域其实是同一件事情。如果当前画笔是NULL_PEN的话,画出来的是没有边框的填充区域;如果当前
??画刷是NULL_BRUSH的话,那么中仍边线而没有填充。
??
??函数????????????????????????????说明
??Rectangle(hDc,x1,y1,x2,y2)????????????????画以(x1,y1)和(x2,y2)为对角坐标的填充矩形
??RoundRect(hDC,x1,y1,x2,y2,w,h)??????????????画以(x1,y1)和(x2,y2)为对角坐标的填充矩形,四个角以一个小椭圆来画圆角,
?????????????????????????????小椭圆的宽和高为w和h
??Polygon(hDC,lpPoint,5)??????????????????lpPoint指向存放(x1,y1)到(x5,y5)的缓存区,函数
?????????????????????????????从(x1,y)到(x2,y2).....到(x5,y5),再回到(x1,y1),一共画5条直线并填充
??
??Chrod(hDc,x1,y1,x2,y2,x3,y3,x4,y4)?????????????以和Arc函数同样的方法画弧,然后连接弧的两个端点并填充
??
??Pie(hDc,x1,y1,x2,y2,x3,y3,x4,y4)??????????????以和Arc函数同样的方法画弧,然后将弧的两个羰点分别和椭圆中心连接并填充
??Ellipse(hDC,x1,y1,x2,y2)?????????????????以(x1,y1)和(x2,y2)为对角定义一个矩形,然后画矩形相切的椭圆并填充
??
??可以用下面的函数切换填充式:
??invoke????SetPolyFillMode,_hDC,ALTERNATE;间隔填充
??invoke????SetPolyFillMode,_hDC,WINDOWG;填充全部区域
??
??除了这些函数,还有3个和矩形相关的填充函数:FillRect,FrameRect和InvertRect,这些函数不使用当前画笔画边线,也不用
??当前画刷填充,其中FillRect函数用指定的画刷hBrush填充一个lpRect指定的矩形区域,lpRect指向一个RECT结构;FrameRect函数
??用来指定画刷hBrush绘 画边线;InvertRect函数将lpRect指定的矩形区域中的颜色取反。用法如下:
??invoke??FillRect,hDC,lpRect,hBrush
??invoke??FrameRect,hDC,lpRect,hBrush
??invoke??InvertRect,hDC,lpRect
??
??我们知道对于DC上被 绘画上去的像素来说,相当于用画笔(或画刷)的像素点代替原来的像素点,但Window
??也可以用画笔的像素点和原来的像素点进行计算以后的值当做新的像素点,这个的过程就叫做光栅运算,光栅运算的方法用
??"光栅运算符"来定义--英文缩写是ROP(Raster Operation),ROP码是一些取反、异或、拷贝及与运算方法的组合,对于绘图函数,
??WindowS定义了16种ROP码
???????????????绘图模式中可以使用的ROP码
??ROP码????????????新像素点算法????????????????????说明
??R2_BLACK????????????0????????????????????????总为黑色
??R2_WHITE????????????1????????????????????????总为白色
??R2_NOP?????????????像素??????????????????????保持不变
??R2_NOT?????????????not(像素) ????????????????????原来像素的颜色取反
??R2_COPYPEN???????????画笔??????????????????????画笔颜色
??R2_NOTCOPYPEN?????????not(画笔)?????????????????????画笔颜色取反
??R2_MERGEPENNOT????????画笔 or not(像素)?????????????????画笔颜色与原像素取反后值的复合
??R2_MASKPENNOT?????????画笔and not(像素)?????????????????画笔和原像素取反后的共同色
??R2_MERGENOTPEN????????像素or not(画笔)?????????????????原像素与画笔取反颜色的复合
??R2_MASKNOTPEN?????????像素and not(画笔)?????????????????原像素和画笔取反后的共同色
??R2_MERGEPEN??????????像素or画笔???????????????????画笔颜色与原来像素的复合
??R2_NOTMERGEPEN????????not(像素or画笔)??????????????????R2_MERGEPEN再取反
??R2_MASKPEN???????????像素and 画笔??????????????????画笔和原来像素的共同色
??R2_NOTMASKPEN?????????not(像素and画笔)?????????????????R2_MASKPEN再取反
??R2_XORPEN???????????像素xor画笔???????????????????画笔和原来像素的异或值
??R2_NOTXORPEN??????????not(像素xor画笔)?????????????????R2_XORPEN再取反
??
??invoke??SetROP2?,hDC,R2_NOTCOPYPEN
??invoke??GetROP2,hDC
??块传送函数
??PatBlt函数完成的是"图案块传送"的功能,即"Pattern Block?Transfer",使用的方法是:
??invok??PatBlt,hDC,xDest,yDest,dwWidth,dwHeight,dwROP
??dwROP中的ROP码指定了传送方式(主要是一些运算)
??BitBlt函数能完成的工作BitBlt函数都能完成,BitBlt是"数据块传送"的意思,即"Bit Block Transfer'.
??invoke??BitBlt?hDcDest,xDest,yDest,dwWidth,dwHeight,hDcSrc,ySrc,dwROP
??MaskBlt函数允许在一个图片中对不同的部分以不同的ROP码进行操作。
??invoke?MaskBit,hDcDest,xDest,yDest,dwWidth,dwHeight,hDcSrc,xSrc,ySrc,hMaskBmp,xMask,yMask,dwROP
??它和BitBlt的不同之处是多个遮掩图片句柄hMaskBmp(注意,是位图句柄而不是DC句柄)以及hMaskBmp的开始坐标。
??其中dwROP是两个ROP码的组合。
??PlgBlt函数实现平行四边形旋转传送操作(Parallelogram Block Transfer),它复制一幅位图,同时将其转换成一个平行四边
??形,所以利用它可以对位图旋转处理。PlgBlt函数的使用语法是:
??invoke?PlgBlt,hdcDest,lpPoint,hdcSrc,xSrc,ySrc,dwWidth,dwHeight,hBmpMask,xMask,yMask
??TransparentBlt函数
??可以实现不规则区域的像素拷贝操作,那就是TransparentBlt函数,它的用法:
??invoke?TransparentBlt,hDcDest,yDest,dwWidthDest,dwHeightDest,hDcSrc,xSrc,ySrc,dwWidthSrc,dwHeightSrc,drTransparent
??
?使用区域
?创建区域
?invoke?CreateRectRgn,dwLeft,dwTop,dwRight,dwBottom
?invoke?CreateEllipticRgn,dwLeft,dwTop,dwRight,dwBottom
?invoke?CreateEllipticRgnIndrect,lpRect
?invoke?CreatePolyRgn,lpPoint,iCount,iPolyFillMode
?invoke?CreateRoundRectRgn,dwLeft,dwTop,dwRight,dwBottom,dwWidthEllipse,dwHeightEllipse
?合并区域
?invoke?CombineRgn,hDestRgn,hSrcRgn1,hSrcRgn2,dwCombine
?
?区域的用途
?使用SetWindowRgn函数可以使窗口的形状由区域指定。
?invoke?CreateEllipticRgn,0,0,0,Clock_size+1,Clock+size+1
?push eax
?invoke?SetWindwRgn,hWinMain,eax,TRUE
?pop?eax
?invoke?DeleteObject,eax
?
?通用对话框
?通用对话框函数由Comdlg32.dll提供,所以在使用之前需要在源程序中包含相应的include和includelib语句:
??include???comdlg32.inc
??includelib??comdlg32.lib
??显示"打开" 文件对话框的函数是GetOpenFileName,显示"保存"文件对话框的函数是GetSaveFileName.这两个对话框可以让用户选择驱动器、
??目录以及一个文件名(打开文件对话框还允许选择多个文件),但这两个对话框并不对文件进行任何操作,
??invoke?GetOpenFileName,lpofn;显示打开文件对话框
??invoke?GetSaveFileName,lpofn;显示保存文件对话框
??lpofn参数是一个指针,指向一个OPENFILENAME结构,程序在调用函数前需要在结构中填写初始化数据,两个函数使用结构是一样的。
??"选择字体"通用对话框:
??invoke?ChooseFont,ipcf
??lpcf指向一个CHOOSEFONT结构。
??选择颜色对话框
??invoke?ChooseColor,lpcc
??lpcc指向一个CHOOSECOLOR结构。查找和替换文本对话框
??invoke?FindText,lpfr
??invoke?ReplaceText,lpfr
??这个两个函数都 使用同样的FINDREPACE结构。
??页面设置对话框
??invoke?PageSetupDlg,lppsd
??lppsd参数指向一个PAGESETPDLG结构。
??浏览目录对话框
??它是由Shell32.dll提供的,使用
??include??shell32.inc
??include?lib?shell32.lib
??显示对话框功能由SHBrowseForFolder函数实现,函数的用法是:
??invoke?SHBrowerForFolder,lpbi
??mov??lpItemIDList,eax
??参数lpbi指向一具包含对话框初始化数据的BROWSEINFO结构。
??程序也可以发送BFFM_SETSELECTION 消息来设定上目录:
??invoke?SendMessage,hWnd,BFFM_SETSELECTION,TRUE,lpPath
??获取返回的目录
??invoke?SHGGetPathFromList,lpItemIDList,add?szPath
??函数执行后,szPath中就是字符串格式的用户选择的目录名称了。
??
??通用控件
??大部分控件由Comctl32.dll模块提供,所以在使用前要在源码程序中包含相应的include和includelib语句:
??include??Comctl32.inc
??includelib?Comctl32.lib
??
??????????????????通用控件
控件名称??????????????预定义的窗口类???????说明???????????特殊风格
Animation Controls??????????SysAnimate32?????????动画????????????ACS_
Header?Controls???????????SysHeader32?????????标题???????????HDS_
ListView Controls??????????SysListView32?????????列表视图?????????LVS_
TreeViewControls??????????SysTreeView32????????树型视图?????????TVS_
ProgressBar????????????msctls_progress32???????进度条
Status Windows???????????msctls_statusbar32??????状态栏??????????SBAR_
HotKey?Control????????????msctls_hotkey32????????热键???????????
Trackbar??????????????msctls_tarbar32????????跟踪条??????????TBS_
Tooltip Control????????????ToolbarWindow32??????工具栏??????????TBSTYLE_
ImageLists??????????????????????????图象列表
PropertySheets????????????????????????属性列表
PropertySheetsPage??????????????????????属性页
DragList???????????????????????????能处理拖放功能的列表框

高级版本的Comctl32.dll(IE4.0以上版本更新的Comctl32.dll文件)?中,还包括了一些扩展的通用控件,这些扩展如下:
Rebar?Controls???????????ReBarWindow32??????IE风格工具栏?????????RBS_
Data &?Time Picker??????????SysDateTimePick32????日期时间???????????DTS_
IP?Address Picker??????????SysIPAddress32??????IP地址输入??????????
Pager Control????????????SysPager????????????????????????PGS_
ComboBoxEx????????????ComboBoxEx32??????扩展ComboBox?????????CBS_

Richedit控件也是一个很常用的控件,可以用来编辑格式的rtf文件和不带格式 的txt文件。
初始化通用控件,函数如下:
invoke?InitCommonControls
没有返回值,只注册第一个控件列表
如要想注册第二个控件列表,用
invoke?InitCommonControlsEx,lpInitCtrls
lpInitCtrls参数指向一个INITCOMMONCONTROLSEX结构


PropertySheet函数---用来创建属性表格
CreatePropertySheetPage函数----用来创建属性页
ImageList_Create函数----用来创建图像列表
MakeDragList函数----用来创建DragList控件

注:在使用控件时要的牢记的是:大部分的控件是窗口。

通用控件也通过发送消息来和父窗口通信
工具栏控件使用WM_COMMAND消息将按钮动作通知父窗口。
滚动条控件使用WM_VSCROLL或者WM_HSCROLL消息 通知父窗口。
除了上面这两种特殊情况,大部分控件使用WM_NOTIFY消息通知父窗口,这样可以避免和菜单或加速键等使用的WM_COMMAND消息相混淆。
当父窗口收到WM_NOTIFY消息时,wParam参数的内容是通用控件的ID,也就是使用CreateWindowEx函数创建控件时使用的第10参数,通过这个参数可以判另WM_NOTIFY
消息是由哪个控件发送的;

热点排行