32位汇编语言学习笔记(30)--rep movsb指令

来源:互联网 发布:linux vi 滚动几行 编辑:程序博客网 时间:2024/04/30 05:46


在《32位汇编语言学习笔记(19)--缓冲区溢出实验》中,我们曾遇到过一个字符串指令:repnz scas,现在我们要学习另外一个字符串指令:rep movsb。
首先看一个小程序:

section .dataEditBuff: db 'abcdefghijklm         ',10BUFFERLEN equ $-EditBuffENDPOS    equ 12INSRTPOS  equ 0section .textWriteStr:push eax; Save pertinent registerspush ebxmov eax,4; Specify sys_write callmov ebx,1; Specify File Descriptor 1: Stdoutint 80H; Make the kernel callpop ebx; Restore pertinent registerspop eaxret; Go homeglobal_start_start:nopmov ecx,EditBuffmov edx,BUFFERLENcall WriteStrstd; Up-memory transfermov ebx,EditBuff+INSRTPOSmov esi,EditBuff+ENDPOS; Start at end of textmov edi,EditBuff+ENDPOS+1; Bump text right by 1mov ecx,ENDPOS-INSRTPOS+1; # of chars to bumprep movsb; Move 'em!mov byte [ebx],' '    mov ecx,EditBuffmov edx,BUFFERLENcall WriteStrExit:mov eax,1; Code for Exit Syscallmov ebx,0; Return a code of zeroint 80H; Make kernel call

程序分析:
 mov ecx,EditBuff  
 mov edx,BUFFERLEN 
 call WriteStr      //打印字符串的初值

 std    //std指令,设置DF标志位,这会使得rep movsb执行循环拷贝操作时,源地址和目的地址变化方向是从高到低。
 mov ebx,EditBuff+INSRTPOS //ebx= EditBuff
 mov esi,EditBuff+ENDPOS  //esi = &EditBuff[12],esi是rep movsb的源地址,指向’m’。
 mov edi,EditBuff+ENDPOS+1 //edi= &EditBuff[13],edi是rep movsb的目的地址,指向第一个空格。
 mov ecx,ENDPOS-INSRTPOS+1 //ecx=13,用于rep movsb的循环计数器
 rep movsb   //通过循环把源地址的数据拷贝到目的地址上,每循环一次ecx就会减1,esi和edi也会减1,当ecx=0时终止循环。执行顺序是:先判断ecx是否为0,如果非0,进行拷贝操作,然后ecx=ecx-1,edi=edi-1,esi=esi-1,进入下一次循环,否则退出循环。因此,循环次数是13。
 mov byte [ebx],' ' // EditBuff[0]=’ ’

 mov ecx,EditBuff  
 mov edx,BUFFERLEN 
 call WriteStr //打印修改后的字符串。

makefile文件:

movsbdemo: movsbdemo.old -o movsbdemo movsbdemo.omovsbdemo.o: movsbdemo.asmnasm -f elf -g -F stabs movsbdemo.asm -l movsbdemo.lst

测试:

[root@bogon movsbdemo]# makenasm -f elf -g -F stabs movsbdemo.asm -l movsbdemo.lstld -o movsbdemo movsbdemo.o[root@bogon movsbdemo]# ./movsbdemo abcdefghijklm          abcdefghijklm        




0 0
原创粉丝点击