比如要设计链表,需要动态分配内存,在汇编下如何实现?
汇编里边还是用栈方便, 省去调系统调用的麻烦
懂了,是通过系统调用。在Linux下,用brk():brk:brk() 是一个非常简单的系统调用。还记得系统中断点吗?该位置是进程映射的内存边界。brk() 只是简单地将这个位置向前或者向后移动,就可以向进程添加内存或者从进程取走内存。
原帖由 TAW 于 2006-10-28 20:53 发表比如要设计链表,需要动态分配内存,在汇编下如何实现?
>>>>>>刚看来的,不知道是否有帮助:>>>>.386
_TEXT segment 'CODE'
assume ds:_TEXT
org 100h
start:mov bx, offset l_end ; 程序的最后add bx, 0fh ; 向上取整到节shr bx, 4 ; bytes -> para.smov ah, 4ah ; 调整内存分配int 21h ; es 指向了 psp 不需设置了push dsmov ax, 40hmov ds, ax ; ds 指向 0040 bios 数据区mov ax, ds:[4eh] ; 当前显示页的起始偏址mov vidBuf, axmov ax, ds:[4ah] ; 当前屏幕的列数xor bx, bxmov bl, ds:[84h] ; 屏幕行数减 1inc blmul bxmov cs:iLength, ax ; 屏幕上的总的字符数shl ax, 1 ; 每个字符占两个字节add ax, 0fh ; 向上取整到节shr ax, 4 ; 字节 -> 节mov bx, axmov ah, 48h ; 为屏幕保存分配内存int 21hpop dsjc l_errAllocMem ; 失败, 转走mov cx, iLength ; 待保存的字符数mov savSeg, ax ; 保存该段址mov es, ax ; 保存的屏幕的内存的段址mov ax, 0b800h ; 指向视频缓冲区, 段址mov si, vidBuf ; 视频缓冲区偏址mov ds, axxor di, di ; 保存的屏幕的内容的偏址, 由 0 始cldrep movsw ; 保存屏幕上的原来的内容mov ax, dsmov es, ax ; es 指向 B800 视频缓冲区, 段址mov ax, csmov ds, ax ; ds 重新指向自己l_fillscr:mov cx, iLengthxor di, dimov al, char2Fill ; 用来填充屏幕的字符mov ah, attr2Fill ; 相应的字符的属性rep stosw ; 填充屏幕l_waitkey:mov ah, 0int 16h ; 等待键盘输入cmp al, 1bh ; <Esc> ?je l_restscr ; yes, 转去恢复屏幕cmp ah, 49h ; <PgUp> ?je l_upchar ; yes, 转去上升字符cmp ah, 51h ; <PgDn> ?je l_dnchar ; yes, 转去递减字符cmp ah, 48h ; <Up> ?je l_upColor ; yes, 转去上升字符颜色cmp ah, 50h ; <Down> ?je l_dnColor ; yes, 转去递减字符颜色cmp ah, 4bh ; <Left> ?je l_dnBkcolor ; yes, 转去递减字符背景色cmp ah, 4dh ; <Right> ?jne l_waitkey ; no, 转去继续等待按键l_upBkcolor:mov al, attr2Fillshr al, 4inc aland al, 0fhand attr2Fill, 0fhshl al, 4or attr2fill, aljmp l_fillscr
l_dnBkcolor:mov al, attr2Fillshr al, 4dec aland al, 0fhand attr2Fill, 0fhshl al, 4or attr2fill, aljmp l_fillscr
l_upColor:mov al, attr2Fillinc aland al, 0fhand attr2Fill, 0f0hor attr2fill, aljmp l_fillscr
l_dnColor:mov al, attr2Filldec aland al, 0fhand attr2Fill, 0f0hor attr2fill, aljmp l_fillscr
l_upchar:mov al, char2Fillinc char2Fillcmp al, 'Z'jne l_fillscrmov char2Fill, 'A'jmp l_fillscr
l_dnchar:mov al, char2Filldec char2Fillcmp al, 'A'jne l_fillscrmov char2Fill, 'Z'jmp l_fillscr
l_restscr:mov cx, iLengthmov di, vidBufmov ax, savSegmov ds, axxor si, sirep movswl_freemem:mov ax, dsmov es, axmov ah, 49hint 21h ; 释放刚申请的用于保存屏幕的内存块xor al, al
l_exit:mov ah, 4chint 21h ; 程序结束, 返回到 DOS
l_errAllocMem:push axmov ah, 9mov dx, offset errAllocMemint 21h ; 显示分配内存失败信息pop ax ; 分配出错的错误代码在 AL 中jmp l_exit
iLength dw 0savSeg dw 0char2Fill db 'A'attr2Fill db 017hvidBuf dw 0errAllocMem db 'Error occurred while allocating memory for screen saving!', '$'
l_end = $
_TEXT ends
end start
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
暂无简介
文章 0 评论 0
接受
发布评论
评论(3)
汇编里边还是用栈方便, 省去调系统调用的麻烦
懂了,是通过系统调用。在Linux下,用brk():
brk:brk() 是一个非常简单的系统调用。还记得系统中断点吗?该位置是进程映射的内存边界。brk() 只是简单地将这个位置向前或者向后移动,就可以向进程添加内存或者从进程取走内存。
>>
>>
>>刚看来的,不知道是否有帮助:
>>
>>
.386
_TEXT segment 'CODE'
assume ds:_TEXT
org 100h
start:
mov bx, offset l_end ; 程序的最后
add bx, 0fh ; 向上取整到节
shr bx, 4 ; bytes -> para.s
mov ah, 4ah ; 调整内存分配
int 21h ; es 指向了 psp 不需设置了
push ds
mov ax, 40h
mov ds, ax ; ds 指向 0040 bios 数据区
mov ax, ds:[4eh] ; 当前显示页的起始偏址
mov vidBuf, ax
mov ax, ds:[4ah] ; 当前屏幕的列数
xor bx, bx
mov bl, ds:[84h] ; 屏幕行数减 1
inc bl
mul bx
mov cs:iLength, ax ; 屏幕上的总的字符数
shl ax, 1 ; 每个字符占两个字节
add ax, 0fh ; 向上取整到节
shr ax, 4 ; 字节 -> 节
mov bx, ax
mov ah, 48h ; 为屏幕保存分配内存
int 21h
pop ds
jc l_errAllocMem ; 失败, 转走
mov cx, iLength ; 待保存的字符数
mov savSeg, ax ; 保存该段址
mov es, ax ; 保存的屏幕的内存的段址
mov ax, 0b800h ; 指向视频缓冲区, 段址
mov si, vidBuf ; 视频缓冲区偏址
mov ds, ax
xor di, di ; 保存的屏幕的内容的偏址, 由 0 始
cld
rep movsw ; 保存屏幕上的原来的内容
mov ax, ds
mov es, ax ; es 指向 B800 视频缓冲区, 段址
mov ax, cs
mov ds, ax ; ds 重新指向自己
l_fillscr:
mov cx, iLength
xor di, di
mov al, char2Fill ; 用来填充屏幕的字符
mov ah, attr2Fill ; 相应的字符的属性
rep stosw ; 填充屏幕
l_waitkey:
mov ah, 0
int 16h ; 等待键盘输入
cmp al, 1bh ; <Esc> ?
je l_restscr ; yes, 转去恢复屏幕
cmp ah, 49h ; <PgUp> ?
je l_upchar ; yes, 转去上升字符
cmp ah, 51h ; <PgDn> ?
je l_dnchar ; yes, 转去递减字符
cmp ah, 48h ; <Up> ?
je l_upColor ; yes, 转去上升字符颜色
cmp ah, 50h ; <Down> ?
je l_dnColor ; yes, 转去递减字符颜色
cmp ah, 4bh ; <Left> ?
je l_dnBkcolor ; yes, 转去递减字符背景色
cmp ah, 4dh ; <Right> ?
jne l_waitkey ; no, 转去继续等待按键
l_upBkcolor:
mov al, attr2Fill
shr al, 4
inc al
and al, 0fh
and attr2Fill, 0fh
shl al, 4
or attr2fill, al
jmp l_fillscr
l_dnBkcolor:
mov al, attr2Fill
shr al, 4
dec al
and al, 0fh
and attr2Fill, 0fh
shl al, 4
or attr2fill, al
jmp l_fillscr
l_upColor:
mov al, attr2Fill
inc al
and al, 0fh
and attr2Fill, 0f0h
or attr2fill, al
jmp l_fillscr
l_dnColor:
mov al, attr2Fill
dec al
and al, 0fh
and attr2Fill, 0f0h
or attr2fill, al
jmp l_fillscr
l_upchar:
mov al, char2Fill
inc char2Fill
cmp al, 'Z'
jne l_fillscr
mov char2Fill, 'A'
jmp l_fillscr
l_dnchar:
mov al, char2Fill
dec char2Fill
cmp al, 'A'
jne l_fillscr
mov char2Fill, 'Z'
jmp l_fillscr
l_restscr:
mov cx, iLength
mov di, vidBuf
mov ax, savSeg
mov ds, ax
xor si, si
rep movsw
l_freemem:
mov ax, ds
mov es, ax
mov ah, 49h
int 21h ; 释放刚申请的用于保存屏幕的内存块
xor al, al
l_exit:
mov ah, 4ch
int 21h ; 程序结束, 返回到 DOS
l_errAllocMem:
push ax
mov ah, 9
mov dx, offset errAllocMem
int 21h ; 显示分配内存失败信息
pop ax ; 分配出错的错误代码在 AL 中
jmp l_exit
iLength dw 0
savSeg dw 0
char2Fill db 'A'
attr2Fill db 017h
vidBuf dw 0
errAllocMem db 'Error occurred while allocating memory for screen saving!', '$'
l_end = $
_TEXT ends
end start