我看的是《IBM-PC汇编语言程序》(第二版) ---沈美明 温冬婵 编著
第235页 例6.12,对其中的第二个子程序movstring看不明白,谁能帮忙分析一下:
书中的原文如下:共四个流程图附后。
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
《IBM-PC汇编语言程序》(第二版) ---沈美明 温冬婵 编著
第235页 例6.12
位串插入程序。程序要求把一个小于32位的位串插入存储器内的一个大位串中的任意位置中去。欲插入的位串存入在bitsg中,它是一个右对齐的位串,可称其为子串,其长度用bitsg_length为符号名的= 伪操作来说明。大位串存入在string中,并为要插入的子串准备了一个符号名为sg_end的双字单元。这里用双字来定义位串的原因在于双字处理位串可以获得更快的速度。
〖说明〗
这一程序主要由移动大位串位置和插入子程序这两个子程序组成,程序框图见图6.7,程序则见下面“例6.12位串插入程序”。主程序中除调用子程序外,主要是作进入子程序条件的判断。一是对子串长度的限制是:0 < 子串长度 < 32;二是测试子串插入的位偏移(即在大位串中子串插入的起始偏移位置)与大位串位位置关系。如果正好在大位串尾,则可直接把子串接在大位串之后;如果已超出大位串的范围,则退出程序不作处理;只有在大位串范围之内时,才调用子程序完成本程序所规定的任务。
移动大位串位置子程序要完成的任务是为了插入子串而移动大位串的位位置。这一工作分两步完成。
第一步,先移动好插入位偏移所在的双字之后的其余双字,这些双字应从尾部开始后移,其后移位数应等于插入串长度(参见图6.8)。这部分程序是在该子程序的LOOP指令之前。其中,要移动的双字数 = 大位串双字数 — 插入位偏移所在的双字地址。
第二步,移动插入位偏移所在汉字。这里要注意的是,插入位偏移之前的各位应保持原位置不变,而其后各位应后移插入串长度位。
在这一子程序中,多处用到双字长度位指令shld和shrd。应注意该指令执行完成后,目的寄存器提到所移入的新内容,而源寄存器则维持原状不变。
插入位串子程序的任务是按指定的插入位偏移插入子串。也就是,用指定的子串取代原有该位置的值。在程序中,先取出插入位偏移所在的双字与其相邻的高阶双字,然后用一串移位指令来达到既移入新子串,又不影响子串外原来的两个双字的内容。
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
例 6.12 位串插入程序
.model small
.386
.stack 200h
.data
bitsg dd 7fffh
string dd 12345678h,12345678h, 12345678h,12345678h
sg_end dd ?
bit_offset dd 58
bitsg_length = 15
.code
;------------------------------------------------------------------------------------------------------
main proc
start: mov ax,@data
mov ds,ax
mov es,ax
;
mov cx,bitsg_length
cmp cx,0
je exit
cmp cx,32
jae exit
mov edi,bit_offset
mov ecx,(sg_end-string)/4
shl ecx,5
cmp edi,ecx
ja exit
jb move
mov esi,bitsg
mov sg_end,esi
jmp exit
;
move: call mov_string
call insert_bitsg
;
exit: mov ax,4c00h
int 21h
;
main endp
;------------------------------------------------------------------------------------------------------------
mov_string proc
sub eax,eax
std
mov si,offset sg_end-4
mov di,offset sg_end
mov ecx,(sg_end-string)/4
mov ebx,bit_offset
shr ebx,5
sub ecx,ebx
next: mov ebx,[si]
shld eax,ebx,bitsg_length
stosd
mov eax,ebx
sub si,4
loop next
sub ebx,ebx
sub edx,edx
mov ecx,bit_offset
and cl,1fh
shrd ebx,eax,cl
shld edx,ebx,cl
shl eax,bitsg_length
mov ebx,-1
shl ebx,cl
and eax,ebx
or eax,edx
mov [edi],eax
ret
mov_string endp
;------------------------------------------------------------------------------------------------------------
insert_bitsg proc
mov esi,bitsg
mov edi,bit_offset
mov ecx,edi
shr edi,5
shl edi,2
and cl,1fh
mov eax,string[edi]
mov edx,string+4[edi]
mov ebx,eax
shrd eax,edx,cl
shrd edx,ebx,cl
shrd eax,esi,bitsg_length
rol eax,bitsg_length
mov ebx,eax
shld eax,edx,cl
shld edx,ebx,cl
mov string[edi],eax
mov string+4[edi],edx
ret
insert_bitsg endp
;------------------------------------------------------------------------------------------------------------
end start