1.字符串的定义
通常情况下,汇编语言中的字符串,都会被赋予DB(字节)数据类型,使用DB作为数据类型的时候,字符串长度不受限制,默认字符串的每一个字符占一个字节,并且存储过程中,是按照一个字符占一个字节的方式,顺序依次存储的。
通过伪指令db定义变量字符串变量: msg
2.字符串的长度计算
$就是当前地址, $ – msg 就是当前地址减去msg的初始地址,即可的字符msg的长度。把计算的长度值赋给len,如上图所示。
我们将使用一种叫做指针运算的技术来计算字符串的长度。两个寄存器被初始化执行内存中相同的地址。每有一个字符,寄存器(EAX)将向前递增1字节,直到我们到达字符串的末尾。然后从EAX减去初始指针。实际上像两个数组之间作差,结果得到两个地址之间元素的个数。然后将这个结果传到sys_write作为字符串的长度。
代码如下:通过伪指令定义msg字符串变量,字符串内容为:Hello, new world!
helloWorld-len.S 代码
section .data
msg db 'Hello, new world!', 0Ah ; 指定msg变量为消息字符串
section .text
global _start
_start:
mov ebx, msg ; 将字符串的地址传给EBX
mov eax, ebx ; 将传给EBX的地址也传给EAX
nextchar:
cmp byte [eax], 0 ; 将EAX指向的字节与0做比较(0是字符结束的分隔符)
jz finished ; 跳转 (如果ZF标记被设置) 跳转到标签'finished'指向的代码
inc eax ; EAX中的地址增加1字节 (如果ZF标记没有被设置)
jmp nextchar ; 跳转到标签'nextchar'指向的代码
finished:
sub eax, ebx ; 将EAX中的地址减去EBX的地址
; 两个寄存器开始指向相同的地址
; 但是字符串没有一个字符EAX的地址就加一
; 当你用一个地址减去另一个地址时
; 结果就是它们之前的份数 - 在本例中就是字节数
mov edx, eax ; EAX 现在就是我们的字节数
mov ecx, msg ; 将字符的内存地址复制到ECX寄存器
mov ebx, 1 ; 写到标准输出
mov eax, 4 ; 调用sys_write (kernel opcode 4)
int 80h
mov ebx, 0 ; 返回状态值0退出,无错误
mov eax, 1 ; 调用sys_exit (kernel opcode 1)
int 80h
CMP指令比较左右两侧并设置用于程序流的若干标志。这个标志我们验证ZF或0标志。当EAX指向的字节等于0时,ZF标志被设置。我们使用JZ指令题跳转,如果ZF标志被设置,跳转到指向我们的程序标签 'finished'。这是用来结束 nextchar 循环并继续执行中止的程序。
编译链接后,执行,如下图
———END———
限 时 特 惠: 本站每日持续更新海量各大最新【内部创业教程】,一年会员只需 98 元,全站资源免费下载 点击查看详情
站 长 微 信: webprojs_com
声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。