【我所認知的BIOS】->汇编语言之宏汇编2By LightSeed2010-2-3 在上一节详细讲了宏汇编的理论,那这节来聊聊我在仿写ADU的时候用的一些宏汇编的例子吧。有了下面这个串宏汇编,那么程序的可维护性就高了很多,在添加或者删除这个工具的功能的时候,就显得格外简单和高级语言写出来的工具的健壮性可媲美。这也是我对这个工具感觉做的最好的地方之一,和大家share一下。(不过这个算法是仿照award bios中setup下面的菜单来做的。)代码如下:1、主要宏;-------------------------------------------------------------------------;******* By LightSeed;******* lightseed@163.com;******* 2010-2-3;;Macro name: CreateMainItem;input :; Name :Name of this item; MorS :mainmenu or submenu; IBT :item belong to (which item 1,2..8 etc); ORD :item order in its menus 0~8 for main item,9~255 for subitem; MaxSubNum :the highest value of submenu; MaxSubMenuStrNum:the number of submenu's string.; MaxStrNum :the maximal number of strings to display; IsHighLit :set if it is choosed; SubitemNum:the number of subitem; Attrib :attribute of this main item; X_axis :row number in window under DOS; Y_axis :line number in window under DOS; _item_str :offset address of strings to display;;ex:; Name =xxxx will be created ' xxxx_item lable near'; MorS =00h means mainmenu,; 01h submenu; othersreserved; IBT when it is mainmenu,IBT no use; when it is submenu,IBT belong to 1--F1,2--F2...etc; ORD =00h default to order; =01h means the first order; ...; MaxSubNum =04h means it can be defined 4 subitems at most; MaxStrNum =05h means it can be defined 5 strings to be displayed; IsHighLit =01H have been highlight; SubitemNum=0hhave no subitem; Attrib =00011110b blackgroud:blue front:yellow; X_axis ; Y_axis; _item_str xxxxxhoffset address;;remark: there will be define a set of structure ,4 data will be filled soon; this macro must be defined with Create_String and EndCreateItem_Str.; because,there are some parameters should be put; ex:; CreateMainItem xx,xx,xx,xx,...; Create_String xx_label; db x,x,x,x,x,x; EndCreateItem_Str ;------------------------------------------------------------------------- CreateMainItem macro Name,MorS,IBT,ORD,MaxSubNum,MaxSubMenuStrNum, MaxStrNum,IsHighLit,SubitemNum,Attrib,X_axis,Y_axis,_item_str Check_Input_ErrorName,%IBT,%MaxSubNum,%MaxStrNum,%MorS Create_Item_Content Name, %MorS, %IBT, %ORD, %MaxSubNum,/ %MaxStrNum,%IsHighLit,%Attrib,%Item_Num,%SubitemNum db Name&_MorS db Name&_IBT db Name&_ORD db Name&_MaxSubNum db MaxSubMenuStrNum db Name&_MaxStrNum db Name&_IsHighLit db Name&_SubitemNum db Name&_Attrib db Name&_Str_Itm_Num ;Display_String_Num,will be place here db Y_axis ;Yaxis db X_axis ;Xaxis dw offset Name&_Str ;offset address Display string endm;CreateMainItem 上面的这个宏的功能主要是创建一个结构体,这个结构体是对每个出现在工具中的item做各个属性的定义的。可以说,这个结构体是画工具界面的主要参数。对于这个创建结构体的宏,内部结构又分三个部分。①对输入的各个参数进行校验,如果出错则输出错误提示信息,编译停止。②经过第一个宏的check后,说明输入数据均是有效的,进而调用另外一个宏来创建一些数据(因为实际输入的数据有些需要进行计算后才填入到结构体中去。这里计算出来的数据均是全局常量,方便在第三部分直接用数据。如果这个定义的数据不放在第二部分的话,那么第三部分在引用这些常量的时候就出错。)。③经过前面两个宏的处理后,对应的数据定义好了(在第二部分中处理好的),直接定义结构体内容。在这个宏里,我们充分看到了在上一节中说的那些宏嵌套和参数引用等问题。2、检验(数据)宏代码如下:;******* By LightSeed;******* lightseed@163.com;******* 2010-2-3 Check_Input_Error macro item_Name,Item_Bel_To,Max_Sub_Num, Max_Str_Num,main_or_sub ;----- if item_Name not declared, then force error ----- ifb %out %out item_Name do not declared! .ERR ENDIF ;----- if IBPT not declared, then force error ----- ifb %out %out where the item belong and point do not declared! .ERR ENDIF ;----- if MaxSubNum not declared, then force error ----- ifb %out %out MaxSubNum not declared! .ERR ENDIF ;----- if MaxStrNum not declared, then force error ----- ifb %out %out MaxStrNum not declared! .ERR ENDIF ;----- if main_or_sub not declared, then force error -----; ifb %out %out main_or_sub not declared! .ERR ENDIF endm;Check_Input_Error对于这个宏,其实我只想说明一点,应该说把上一节的条件汇编用在了这里。3、处理(数据)宏代码如下:;-------------------------------------------------------------------------;******* By LightSeed;******* lightseed@163.com;******* 2010-2-3;;;;Macro name: Create_Item_Content;input :;; Name =xxxx will be created ' xxxx_item label near'; MorS =00h mainmenu; =01h submenu; IBT =00h means mainmenu,; 01h submenu; othersreserved; ORD =00h default to order; =01h means the first order;; MaxSubNum =04h means it can be defined 4 subitems at most; MaxStrNum =05h means it can be defined 5 strings to be displayed; IsHighLit =01H have been highlight; Attrib =00011110b blackgroud:blue front:yellow ;------------------------------------------------------------------------- Create_Item_Content macro Name,MorS,IBT,ORD,MaxSubNum,MaxStrNum,IsHighLit,Attrib,CurrentItemNum,SubitemNum _MorS = MorS _IBT = IBT _ORD = ORD _MaxSubNum= MaxSubNum _MaxStrNum= MaxStrNum ;qe'=' gt'>' lt'<' ge'>=' le'<=' ;when you create a main menu,counter ++ if _MorS eq 0 _TotalMainMenuNum = _TotalMainMenuNum+1 ; endif ;if _TotalMainMenuNum > the highest value then force error if _TotalMainMenuNum gt MaxMainMenuNum %out %OUT The number of mainmenu too large .ERR endif ;if _MaxSubNum > the highest value then force error if _MaxSubNum gt MaxSubMenuNum %out %OUT The number of submenu too large .ERR endif;_MaxSubNum gt MaxSubMenuNum ;if order > the highest value then force error if _MorS eq 0 ;if mainmenu? if _ORD gt MaxMainMenuNum %out %OUT The order of mainmenu too large .ERR endif;_ORD gt MaxMainMenuNum else ;_MorS eq 0 ;it is submenu if _ORD gt MaxSubMenuNum %out %OUT The order of submenu too large .ERR endif;_ORD gt MaxSubMenuNum endif;_MorS eq 0 public Name&_item Name&_itemLabel Near ;create the item ifndefName&_MorS Name&_MorSequMorS endif ifndefName&_IBT Name&_IBT equIBT endif ifndefName&_ORD Name&_ORD equORD endif ifndefName&_MaxSubNum Name&_MaxSubNum equMaxSubNum endif ifndefName&_MaxStrNum Name&_MaxStrNum equMaxStrNum endif ifndefName&_IsHighLit Name&_IsHighLit equIsHighLit endif ifndefName&_SubitemNum ifb Name&_SubitemNum equ 0 else Name&_SubitemNum equSubitemNum endif; endif ifndefName&_Attrib Name&_Attrib equAttrib endif ifndefName&_Str_Itm_Num Name&_Str_Itm_NumequName&_str_&CurrentItemNum; endif ;define offset item OffsetAddress&CurrentItemNum; equoffset Name&_item endm;Create_Item_Content这个宏,看上去很代码很多,其实看清庐山真面目了以后就感觉很简单。那么我就简单说说看这个宏的时候,应该注意的几个问题:①用“=”定义的是一个变量,它可以在宏计算的时候当一个变量来使用,可以被重新赋值。而用“EQU”定义的是一个常量,是不能够加减重新赋值的。②“&”是个连接符,它的作用其实就是为了让变量或者常量看起来,或者说操作起来更直观易懂。③条件汇编在这个宏里用的最多。总的来说,其实这个宏都只是定义了一些常量来供主宏来定义结构体罢了。从这个角度上看,这些定义的常量就类似于函数的输出了。只是中间的逻辑稍微不那么直观而已。 关于宏汇编的东西,我就和大家讲这么两个小节,而且主要是围绕我写的那个工具中用到的宏汇编来写的。(不过我想能够融会贯通这些宏的使用的话,也应该够用了吧。呵呵。。。毕竟人家BIOS也就用了这些嘛。)如果您对此还有什么疑问的话,我们可以再深入交流。