汇编--查找第一个非0字符的五种方法

第一种

#include <windows.h>
#include <stdio.h>

void main(void)
{
    int m = 0, cout = 0;
    char cStr2Find[1024] = {0};
    printf("请输入一段字符串");
    scanf("%s", cStr2Find);
    __asm{
        pushad;                    //保存所有寄存器
        lea esi,cStr2Find;        //esi指向查找字符串
        xor ecx,ecx;            //ecx清零
_loop:
        lodsb;                    //循环得到字符串长度
        or al,al;
        jz _end;
        inc ecx;
        jmp _loop;
_end:
        mov ebx,ecx;            //保存字符串长度到ebx
        inc ecx;
        lea esi,cStr2Find;
_loop1:
        lodsb;                    //循环查找第一个非字符‘0‘的字符
        dec ecx;                //ecx用来判断是否找完字符串
        or ecx,ecx;
        jz _end2;
        cmp al,‘0‘;
        je _loop1;                //不是字符‘0‘就往上跳
        sub ebx,ecx;            //是字符‘0‘,就得到我们对比了多少个字符..
        mov cout,ebx;            //也就是非‘0‘字符在哪个位置
        jmp _end3;
_end2:
        mov cout,-1;
_end3:
        popad;
    }
    printf("非0位置: %d\n",cout);
}

第二种:

#include <windows.h>
#include <stdio.h>

void main(void)
{
    int m = 0, cout = 0;
    char cStr2Find[1024] = {0};
    printf("请输入一段字符串");
    scanf("%s", cStr2Find);
    __asm{
        pushad;                    //保存所有寄存器
        lea edi,cStr2Find;
        mov ecx,-1;
        xor eax,eax;
        repne scas byte ptr es:[edi];
        not ecx;
        dec ecx;                //这一堆指令是计算字符串长度

        mov ebx,ecx;            //ebx是字符串长度

        lea edi,cStr2Find;
        mov eax,0x30;
        repe scas byte ptr es:[edi];    //扫描第一个非0字符
        or ecx,ecx;                //判断扫描玩没?
        je  _panduan;            //扫描完就跳
        sub ebx,ecx;            //没有扫描完说明含有非0字符
        dec ebx;
        mov cout,ebx;            //把位置给cout
        jmp _end;
_panduan:                    //注意,如果最后一个字符是非0,也会跳到这里
        dec edi;
        cmp byte ptr[edi],‘0‘;    //判断最后一个字符是不是字符0
        je _AllAreZero;        //是就跳
        dec ebx;
        mov cout,ebx;        //最后一个字符是非0
        jmp _end;
_AllAreZero:
        mov cout,-1;
_end:
        popad;
    }
    printf("非0位置: %d\n",cout);
}

第三种:

#include <windows.h>
#include <stdio.h>

void main(void)
{
    int m = 0, cout = 0;
    char cStr2Find[1024] = {0};
    printf("请输入一段字符串");
    scanf("%s", cStr2Find);
    __asm{
        pushad;                    //保存所有寄存器
        lea esi,cStr2Find;        //esi指向查找字符串
        lea edi,cStr2Find;

        mov ecx,-1;
        xor eax,eax;
        repne scas byte ptr es:[edi];
        not ecx;
        dec ecx;                //这一堆指令是求字符串长度

        mov ebx,ecx

_loop:
        cmp byte ptr[esi], ‘0‘;
        jne ok;
        inc esi;
        loop _loop;            //循环对比
        mov cout,-1;        //没找到
        jmp _end;
ok:
        sub ebx,ecx;        //找到了
    //    dec ebx;
        mov cout,ebx;
_end:
        popad;
    }
    printf("非0位置: %d\n",cout);
}

第四种:

#include <windows.h>
#include <stdio.h>

void main(void)
{
    int m = 0, cout = 0;
    char cStr2Find[1024] = {0};
    printf("请输入一段字符串");
    scanf("%s", cStr2Find);
    __asm{
        pushad;                    //保存所有寄存器
        lea edi,cStr2Find;
        mov ecx,-1;
        xor eax,eax;
        repne scas byte ptr es:[edi];
        not ecx;
        dec ecx;                //这一堆指令是计算字符串长度

        mov ebx,ecx;            //ebx是字符串长度

        lea esi,cStr2Find;

_loop:
        mov al,‘0‘;
        xor al, byte ptr[esi];
        or al,al;
        jne _ok;
        inc esi;
        loop _loop;                //循环对比是不是字符0
        jmp _AllAreZero
_ok:
        sub ebx,ecx;
        mov cout,ebx;
        jmp _end;
_AllAreZero:
        mov cout,-1;
_end:
        popad;
    }
    printf("非0位置: %d\n",cout);
}

第五种:

#include <windows.h>
#include <stdio.h>

void main(void)
{
    int m = 0, cout = 0;
    char cStr2Find[1024] = {0};
    printf("请输入一段字符串");
    scanf("%s", cStr2Find);
    __asm{
        pushad;                    //保存所有寄存器
        lea edi,cStr2Find;
        mov ecx,-1;
        xor eax,eax;
        repne scas byte ptr es:[edi];
        not ecx;
        dec ecx;                //这一堆指令是计算字符串长度

        mov ebx,ecx;            //ebx是字符串长度

        lea esi,cStr2Find;

_loop:
        mov al,‘0‘;
        sub al, byte ptr[esi];    //sub
        or al,al;
        jne _ok;            //判断是否是非0;
        inc esi;
        dec ecx;        //判断对比完没
        cmp ecx,0;
        je _AllAreZero;    //对比完就跳
        jmp _loop;
_ok:
        sub ebx,ecx;
        mov cout,ebx;
        jmp _end;
_AllAreZero:
        mov cout,-1;
_end:
        popad;
    }
    printf("非0位置: %d\n",cout);
}
时间: 2024-11-08 14:18:25

汇编--查找第一个非0字符的五种方法的相关文章

hdu 1066 Last non-zero Digit in N! (数论——n!中的最后一个非0数字)

Last non-zero Digit in N! Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 6432    Accepted Submission(s): 1593 Problem Description The expression N!, read as "N factorial," denotes the pro

找第一个非0元素的位置

DATA SEGMENTARR DB 0,0,34H,56H,89H,0CNT EQU $-ARRRES DB 0DATA ENDSCODE SEGMENTASSUME CS:CODE,DS:DATABEGIN: MOV AX,DATA MOV DS,AX XOR AX,AX MOV CX,CNT MOV BX,0NEXT: CMP ARR[BX],0 JNZ NEXT1 INC BX LOOP NEXT JNZ EXIT ;如果ZF不等于0即相比都不相等 NEXT1: MOV RES,BLEX

js实现从字符串中查找出现次数最多的字符的两种解决办法

方法一:正则表达式匹配 1 var str = "adadfdfseffserfefsefseeffffftsdg"; 2 var maxLength = 0; var result = ""; 3 while (str != '') { 4 oldStr = str; 5 getStr = str.charAt(0); 6 str = str.replace(new RegExp(getStr, "g"), ""); 7 i

【转】这五种方法前四种方法只支持IE浏览器,最后一个方法支持当前主流的浏览器(火狐,IE,Chrome,Opera,Safari)

<!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8"> <title>html 表格导出道</title> <script language="JavaScript" type="text/javascript"> //第一种方法 function method1(table

让程序只运行一个实例(Delphi篇)(三种方法,其中使用全局原子的方法比较有意思)

Windows 下一个典型的特征就是多任务,我们可以同时打开多个窗口进行操作,也可以同时运行程序的多个实例,比如可以打开许多个资源管理器进行文件的移动复制操作.但有时出于某种考虑(比如安全性),我们要做出一些限制,让程序只能够运行一个实例.在Delphi编程中,笔者总结出了以下几种方法: 一. 查找窗口法 这是最为简单的一种方法.在程序运行前用FindWindow函数查找具有相同窗口类名和标题的窗口,如果找到了,就说明已经存在一个实例.在项目源文件的初始化部分添加以下代码: [delphi] v

汇编32位寄存器和地址编号的五种书写形式

32位通用寄存器 32位:EAX   EBX  ECX   EDX  ESP  EBP   ESI  EDI  每个寄存器的最大宽度是32位 16位:AX       BX     CX    DX   SP     BP    SI     DI 8位   :AL     BL   CL      DL    AH    BH    CH    DH 想寄存器存一个数字可以用mov指令 mov eax,1  就是把1存到eax寄存器中 程序内存 一个32位的程序最大存储空间是4G 就是从0~0

简述linux同步与异步、阻塞与非阻塞概念以及五种IO模型

1.概念剖析 相信很多从事linux后台开发工作的都接触过同步&异步.阻塞&非阻塞这样的概念,也相信都曾经产生过误解,比如认为同步就是阻塞.异步就是非阻塞,下面我们先剖析下这几个概念分别是什么含义. 同步:所谓同步,就是在发出一个功能调用时,在没有得到结果之前,该调用就不返回.也就是必须一件一件事做,等前一件做完了才能做下一件事. 例如普通B/S模式(同步):提交请求->等待服务器处理->处理完毕返回 这个期间客户端浏览器不能干任何事 异步:异步的概念和同步相对.当一个异步过程

linux同步与异步、阻塞与非阻塞概念以及五种IO模型

1.概念剖析 相信很多从事linux后台开发工作的都接触过同步&异步.阻塞&非阻塞这样的概念,也相信都曾经产生过误解,比如认为同步就是阻塞.异步就是非阻塞,下面我们先剖析下这几个概念分别是什么含义. 同步:所谓同步,就是在发出一个功能调用时,在没有得到结果之前,该调用就不返回.也就是必须一件一件事做,等前一件做完了才能做下一件事. 例如普通B/S模式(同步):提交请求->等待服务器处理->处理完毕返回 这个期间客户端浏览器不能干任何事 异步:异步的概念和同步相对.当一个异步过程

让一个元素垂直水平居中的三种方法

第一种方法: div.box{ weight:200px; height:400px; <!--把元素变成定位元素--> position:absolute; <!--设置元素的定位位置,距离上.左都为50%--> left:50%; top:50%; <!--设置元素的左外边距.上外边距为宽高的负1/2--> margin-left:-100px; margin-top:-200px; } *兼容性好;缺点:必须知道元素的宽高 ------------- 第二种方法: