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

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注