2025年4月7日 星期一 乙巳(蛇)年 正月初八 设为首页 加入收藏
rss
您当前的位置:首页 > 计算机 > 编程开发 > 汇编

汇编语言Irivne64字符串过程详解[附带实例]

时间:03-05来源:作者:点击数:73

下面将一些比较重要的字符串处理过程从 Irvine32 链接库转换为 64 位模式。变化非常简单,删除堆栈参数,并将所有的 32 位寄存器都替换为 64 位寄存器。

下表列出了这些字符串过程、过程说明及其输入输出。 

Str_compare 比较两个字符串输入参数:RSI 为源串指针,RDI 为目的串指针返回值:若源串 < 目的串,则进位标志位 CF=1;若源串 = 目的串,则零标志位 ZF=1;若源串 > 目的串,则 CF=0 且 ZF=0
Str_copy 将源串复制到目的指针指向的位置输入参数:RSI 为源串指针,RDI 指向被复制串将要存储的位置
Str_length 返回空字节结束字符串的长度输入参数:RCX 为字符串指针返回值:RAX 为该字符串的长度

Str_compare 过程中,RSI 和 RDI 是输入参数的合理选择,因为字符串比较循环会用到它们。使用这两个寄存器参数能在过程开始时避免将输入参数复制到 RSI 和 RDI 寄存器中:

  • ;------------------------------------
  • ;Str_compare
  • ;比较两个字符串
  • ;接收:RSI 为源串指针
  • ; RDT 为目的串指针
  • ;返回:若字符串相等,ZF 置 1
  • ; 若源串 < 目的串,CF 置 1
  • ;------------------------------------
  • Str_compare PROC USES rax rdx rsi rdi
  • L1: mov al,[rsi]
  • mov dl,[rdi]
  • cmp al, 0 ; string1 结束?
  • jne L2 ; 否
  • cmp dl, 0 ;是:string2 结束?
  • jne L2 ;否
  • jmp L3 ;是:退出且 ZF=1
  • L2: inc rsi ;指向下一个字符
  • inc rdi
  • cmp al,dl ;字符相等?
  • je L1 ;是:继续循环
  • ;否:退出并设置标志位
  • L3: ret
  • Str_compare ENDP

注意,PROC 伪指令用 USES 关键字列出了所有需要在过程开始时入栈、在过程时返回出栈的寄存器。

Str_copy 过程用 RSI 和 RDI 接收字符串指针:

  • ;-------------------------------------
  • ;Str_copy
  • ;复制字符串
  • ;接收:RSI 为源串指针
  • ; RDI 为目的串指针
  • ;返回:无
  • ;-------------------------------------
  • Str_copy PROC USES rax rex rsi rdi
  • mov rex,rsi ;获得源串长度
  • call Str_length ;RAX 返回长度
  • mov rex,rax ;循环计数器
  • inc rex ;有空字节,加 1
  • cld ;方向为正向
  • rep movsb ;复制字符串
  • ret
  • Str_copy ENDP

Str_length 过程用 RCX 接收字符串指针,然后循环扫描该字符串直到发现空字节。字符串长度用 RAX 返回:

  • ;-------------------------------------
  • ;Str_length
  • ;计算辜符串长度
  • ;接收:RCX 指向字符串
  • ;返回:RAX 为字符串长度
  • ;-------------------------------------
  • Str_length PROC USES rdi
  • mov rdi,rex ;获得指针
  • mov eax,0 ;字符计数
  • L1:
  • cmp BYTE PTR [rdi],0 ;字符串结束?
  • je L2 ;是:退出
  • inc rdi ;否:指向下一个字符
  • inc rax ;计数器加 1
  • jmp L1
  • L2: ret ;RAX 返回计数值
  • Str_length ENDP

一个简单的测试程序

下面的测试程序调用了 64 位的 Str_length、Str_copy 和Str_compare 过程。虽然程序中没有显示字符串的语句,但是建议在 Visual Studio 凋试器中运行,这样就可以查看内存窗口、寄存器和标志位。

  • ; 测试 Irvine64 字符串程序
  • Str_compare proto
  • Str_length proto
  • Str_copy proto
  • ExitProcess proto
  • .data
  • source byte "AABCDEFGAABCDFG",0 ; 大小为 15
  • target byte 20 dup(0)
  • .code
  • main proc
  • mov rax,offset source
  • call Str_length ; 用 RAX 返回长度
  • mov rsi,offset source
  • mov rdi,offset target
  • call str_copy
  • ; 由于刚刚才复制了字符串,因此它们应该相等
  • call str_compare ; ZF = 1, 字符串相等
  • ; 修改目的串的第一个字符,再比较两个字符串
  • ; compare them again:
  • mov target,'B'
  • call str_compare ; CF = 1, 源串 < 目的串
  • mov ecx,0
  • call ExitProcess
  • main ENDP
方便获取更多学习、工作、生活信息请关注本站微信公众号城东书院 微信服务号城东书院 微信订阅号
推荐内容
相关内容
栏目更新
栏目热门