-----------------------------------------------------------------------------------------------------------------------------------------
1,100define plus(a,b) ((a)+(b))
2,org是做什么的
--------------------------------------------------------------------------------------
在 NASM汇编语言汇编BIN格式的程序中,举例说明ORG的意义
ORG 100H
START:
movax,START;
……
上面有一个标签 START ,执行mov ax,START时,ax=100h,如果不写ORG 100H,那么就是相当于 ORG0H,这样的话,ax=00h
这就是说,地址引用的数值 = 该地址在文件内的偏移+ org 的数值。更本质的说,org指令是提前告诉编译器:“你正在编译的这段的代码段将来肯定会被加载到内存的XXX地址处”。编译器据此来计算每个标签(label)对应的物理地址。(这句话是我自己加上来的)
--------------------------------------------------------------------------------------
分割线里就讲得很清楚了,摘自http://hi.baidu.com/chinfs/blog/item/535d0eed42866addb21cb18d
3,写一个最原始的echo
----------
%ifndef echo_mac
100define echo_mac
%include"esbp.mac"
%macro echo 1
jmp%%start
%%local:db %1
%strlen bytenum%1
%%start:movcx,bytenum
movah,13h
moval,1h
mov dh,0
movdl,0
movbh,0
movbl,00000100b
esbp%%local
int 10h
%endmacro
%endif
----------
这是esbp.mac文件:
----------
%ifndef esbp_mac
100define esbp_mac
%macro esbp 1
;the address passed here must be a 16-bit digit,namely not greaterthan 0xffff
push ax
push dx
mov ax,%1
mov dx,%1
and dx,0x000f
shr ax,4
mov bp,dx
mov es,ax
pop dx
pop ax
%endmacro
%endif
----------
试试效果如何吧,下面的测试文件boot.asm
----------
%include "echo.mac"
org 0x7c00
start:echo 'hello! oranges world'
times 510-($-start) db 0
dw 0aa55h
----------
编译成bin文件,并dd到虚拟软盘的mbr,bochs调试,如图:
这个石器时代的echo宏就做好啦!
4,稍微增强这个echo的功能,能够将字符串显示到指定行列。下面是echoAtLC.mac
----------
%ifndef echoAtLC_mac
100define echoAtLC_mac
%include "esbp.mac"
%macro echoAtLC 3
jmp %%start
%%local:db %1
%strlen bytenum %1
%%start:mov cx,bytenum
mov ah,13h
mov al,1h
mov dh,%2
mov dl,%3
mov bh,0
mov bl,00000100b
esbp %%local
int 10h
%endmacro
%endif
----------
5,把echo再做强一些,使其能将字符串显示到光标所在位置
思路是:利用int 10h的3号子功能获取光标所在行列,再调用echoAtLC宏就好了。下面是echoUnderCursor.mac
----------
%ifndef echoUnderCursor_mac
100define echoUnderCursor_mac
%include "echoAtLC.mac"
%macro echoUnderCursor 1
;get the line&column cursor locate
push dx
push cx
push ax
push bx
mov ah,3h
mov bh,0
int 10h
pop bx
pop ax
pop cx
echoAtLC %1,dh,dl
pop dx
%endmacro
----------
6,readCursor_D.mac和setCursor_page_line_column.mac
这两个头文件内的宏,分别用来读取光标信息和设置光标位置,即对int 10h的3号和2号子功能的包装
头文件readCursor_D.mac
----------
;change dx
;dh store line,dl store column
%ifndef readCursor_D_mac
100define readCursor_D_mac
%macro readCursor_D 0
push bx
push ax
push cx
mov bh,0
movah,3h
int 10h
pop cx
pop ax
pop bx
%endmacro
%endif
----------
头文件setCursor_page_line_column.mac
----------
;change no reg
%ifndef setCursor_mac
100define setCursor_mac
%macro setCursor_page_line_column 3
push ax
push bx
push dx
mov bh,%1
mov dh,%2
mov dl,%3
movah,2h
int 10h
pop dx
pop bx
pop ax
%endmacro
%endif
----------
此类的头文件越写越多,我开始注意统一规范:例如,第一行注释,讲明这个宏执行后是否对寄存器造成影响,如果是,在宏的名字后统一加_D后缀,像比readCursor_D,_D就是说这个宏dangerous。例如,假如这个宏需要的参数多于2个,我就将参数的名字信息附加到宏的名字里,像比setCursor_page_line_column,这样一看就知道要输入哪些参数。例如,宏的名字尽量跟头文件的名字一样。(当然,不包括.mac后缀部分了)
7,实现光标的回车功能 cursorEnter.mac
----------
;change no reg
%ifndef cursorEnter_mac
100define cursorEnter_mac
%include "setCursor_page_line_column.mac"
%include "readCursor_D.mac"
%macro cursorEnter 0
push dx
readCursor_D
incdh
setCursor_page_line_column 0,dh,0
pop dx
%endmacro
%endif
-----------
8,将光标初始化到0行0列 echoinit.mac
----------
;change no reg
%ifndef echoinit_mac
100define echoinit_mac
%include "setCursor_page_line_column.mac"
%macro echoinit 0
setCursor_page_line_column 0,0,0
%endmacro
%endif
----------
这个宏看起来似乎很没必要,我后来也觉得如此,直接用setCursor_page_line_column0,0,0简单又直观。只是一开始写这个宏的时候,setCursor_page_line_column.mac还没写出来,是写到echoinit.mac时,才想到去写setCursor_page_line_column 0,0,0的。
9,写一个会自动换行的echon.mac
%ifndef echon_mac
100define echon_mac
%include "./echoUnderCursor.mac"
%include "./cursorEnter.mac"
%macro echon 1
echoUnderCursor %1
cursorEnter
%endmacro
%endif
测试以下效果,下面是测试代码boot.asm
----------
%include "echoinit.mac"
%include "cursorEnter.mac"
%include "./echon.mac"
org 0x7c00
start:
echoinit
echon 'hi,this is the first line..'
echon 'the second line..'
echon 'third linenow..'
times 510-($-start) db 0
dw 0aa55h
---------
编译成bin文件,dd到虚拟软盘的mbr,bochs调试,截图:
2012,8,12 吉首