技术交流,DH讲解.

正式之前,我们看看寄存器和CPU的标志位:

OD中的截图,下方的CPAZSTDO就是标志位.
 
Delphi的FPU窗口,右边一列就是标志位.
为什么要给大家看标志位呢?因为ASM中的跳转语句都是由相应的标志位控制的.
而标志位又是由于以下的情况影响的:
1.运算结果为0,Zero Flag(ZF)被设定
2.运算结果太大或者太小,超容了,Carry Flag(CF)被设定
3.Sign Flag(SF)是运算结果的最高位发生变化的时候,结果为正SF=1,为负SF=0
4.指令无效时(al=+127, al+1爆 , al = -128 , al-1爆),Over Flag会被设定
5.运算造成结果的地位中1的个数是偶数个的时候Parity Flag会被设定

指令讲解:
具体指令之前,先说一下:reg代表寄存器,mem代表内存上的数(变量),imm代表立即数(常量)
AND,二元操作符,位与
合法形式:

1
2
3
4
5
AND reg , reg
AND reg , mem
AND reg , imm
AND mem , reg
AND mem , imm

标志位:总是清除OF和CF,根据结果来设置SF,ZF,PF.
来看个例子吧:

1
2
3
4
5
6
7
8
9
10
11
12
function TestAnd(a,b:Integer):Integer ;
asm
  and eax,edx
end;
 
procedure TForm4.FormCreate(Sender: TObject);
var
  a:Integer;
begin
  a:=$F;//00001111
  ShowMessage(IntToStr(TestAnd(a,1)));
end;

 运算前
 运算后
来个有用的函数,字符转换成大写:

1
2
3
4
function UpcaseChar(a:AnsiChar):AnsiChar;
asm
  and al,$DF
end;

OR,二元操作符,位或
合法形式:

1
2
3
4
5
OR reg , reg
OR reg , mem
OR reg , imm
OR mem , reg
OR mem , imm

标志位:和AND一样.
例子将0~9的整数变成对应的Char形式:

1
2
3
4
function _0_9ToChar(n:Byte):AnsiChar;
asm
  or al,$30
end;

 运算前
 运算后

XOR,二元操作符,位异或(相同为0,不同为1)
合法形式:同AND
标志位:同AND
我们有时候需要将某个寄存器清零,我们有2种方式:

1
2
3
4
5
procedure TestXor;
asm
  xor eax,eax
  mov eax,0
end;

反汇编看:
 
第一个指令:$31C0只用了2个字节.第二个指令就用了5个字节.
NOT,一元操作符,位非(1变0,0变1)
合法形式:

1
2
NOT reg
NOT mem

标志位:不影响任何标志位
TEST,二元操作符,和AND的一样,但是不改变2个操作数的值,只影响标志位.
合法形式:同AND
标志位:同AND
我们经常需要判断一个string变量是否为nil

1
2
3
4
5
function TestTest(const s:string):Integer;
asm
  test eax,eax //if s=nil then
  jz @@nExit
end;

CMP,二元操作符,比较2个数大小
合法形式:同SUB指令
标志位:
                CF ZF
目的<來源 | 0 | 1
目的>來源 | 0 | 0
目的=來源 | 1 | 0
带正负号的数比较:
目的<來源 | SF≠OF
目的>來源 | SF=OF
目的=來源 | ZF=1

常用的设置个别标志位的方法:
1 ZF

1
2
and al,0 //ZF=1,任何数和0进行与
or al,1 //ZF=0,任何数和1进行或

2 SF

1
2
or al,$80 //SF=1,最高位与1进行或
and al,$7F //SF=0,最高位与0进行与

3 CF

1
2
stc //CF=1
clc //CF=0

4 OF

1
2
3
mov al,$7F
inc al //OF=1
or al,0 //OF=0

跳转指令
一般跳转根据:1 标志位 2 参与运算的2个数
第一组:N代表Not,J就是Jump,然后其他字母对应相应的标志位
JZ   | 若為零則跳     | ZF=1
JNZ | 若為不零則跳 | ZF=0
JC   | 若進位則跳     | CF=1
JNC | 若不進位則跳 | CF=0
JO   | 若溢位則跳     | OF=1
JNO | 若不溢位則跳 | OF=0
JS    | 若負號則跳    | SF=1
JNS  | 若非負號則跳 | SF=0
JP    | 同位(偶)則跳  | PF=1
JNP | 非同位(奇)則跳 | PF=0
第二组:根据参与运算的2个数的值
JE     | 相等則跳(leftOp=rightOp)
JNE   | 不相等則跳(leftOp≠rightOp)
JCXZ | 若 CX = 0 則跳
JECXZ | 若 ECX = 0 則跳
无符号2个数比较时候:
JA     | 較大則跳 大于
JNBE | 不是較小或相等則跳(=JA) 大于
JAE   | 較大或相等則跳 大于等于
JNB   | 不是較小則跳(=JAE)大于等于
JB     | 較小則跳 小于
JNAE | 不是較大或相等則跳(=JB)小于
JBE   | 較小或相等則跳 小于等于
JNA   | 不是較大則跳(=JBE)小于等于
有符号2个数比较时候:
JG      | 較大則跳
JNLE  | 非較小或相等則跳(=JG)
JGE    | 較大或相等則跳
JNL    | 不是較小則跳(=JGE)
JL      | 較小則跳
JNGE | 非較大或相等則跳(=JL)
JLE    | 較小或相等則跳
JNG   | 不是較大則跳(=JLE) | 不是較大則跳(=JBE)

好我们来看下怎么写一个求2个数中较小的一个数的函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
function IntegerMin(a,b:Integer):Integer;
asm
  cmp eax,edx
  jg @@nBmin
  ret
@@nBmin:
  mov eax,edx
end;
 
function CardinalMin(a,b:Cardinal):Cardinal ;
asm
  cmp eax,edx
  ja @@nBmin
  ret
@@nBmin:
  mov eax,edx
end;

关键处的跳转指令不一样的,因为数据类型不一样.

最后来看一下循环指令
LOOPELOOPZ,一元操作符,满足条件就跳转,条件是ZF=1 and ecx>0
合法形式:LOOPE/LOOPZ 标签

LOOPNELOOPNZ,一元操作符,条件ZF=0 AND ECX>0
合法形式:和LOOPE
我们用LoopE来在一个字符串中查找一个字符

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
function FindChar(a:AnsiChar;const s:AnsiString):Integer ;
asm
  test edx,edx   //s=nil
  jz @@nNotFound
  mov ecx,[edx - 4]
  //length(s)=0
  jz @@nNotFound
  push edx
  dec edx
@@nLoop:
  inc edx
  cmp al,Byte ptr [edx]
  loopne @@nLoop
  pop edx
  test ecx,ecx
  jz @@nNotFound
  mov eax,[edx - 4]
  sub eax,ecx
  dec eax
  ret
@@nNotFound:
  xor eax,eax
end;

好了今天能说的就这么多了.特别感谢http://evotalk.net..都是中国人哈哈.

http://www.cnblogs.com/huangjacky/archive/2010/01/20/1652495.html

ASM - 条件判断的更多相关文章

  1. C# if中连续几个条件判断

    C# if中连续几个条件判断 1.if (条件表达式1 && 条件表达式2) 当条件表达式1为true时 using System; using System.Collections. ...

  2. js条件判断时隐式类型转换

    Javascript 中,数字 0 为假,非0 均为真 在条件判断运算 == 中的转换规则是这样的: 如果比较的两者中有布尔值(Boolean),会把 Boolean 先转换为对应的 Number,即 ...

  3. 5-3 bash脚本编程之二 条件判断

    1. 条件测试的表达式 1. [ expression ]  :注意这个中括号的前后都有一个空格 2. [[ expression ]] 3. test expression 2.条件判断的类型 1. ...

  4. 第10章 Shell编程(3)_字符处理命令和条件判断

    3. 字符处理命令 3.1 排序命令:sort (1)sort命令:#sort [选项] 文件名 选项 作用 -f 忽略大小写 -n 以数值型进行排序,默认使用字符串型排序 -r 反向排序 -t 指定 ...

  5. Nginx if 条件判断

    Nginx if 条件判断: 1.公司网站上线有这样的需求: 由于公司网站域名从http到https的转移,在测试阶段需要公司内部进行测试,公司内部局域网访问时强制访问加密的https服务,外部用户访 ...

  6. shell条件判断与流程控制

    一 条件判断式语句 1.按文件类型进行判断 测试类型 作用 -b 文件 判断文件是否存在,并且是否为块设备文件(是块设备文件为真) -c 文件 判断文件是否存在,并且是否为字符设备文件(是字符设备设备 ...

  7. 为什么说在使用多条件判断时switch case语句比if语句效率高?

    在学习JavaScript中的if控制语句和switch控制语句的时候,提到了使用多条件判断时switch case语句比if语句效率高,但是身为小白的我并没有在代码中看出有什么不同.去度娘找了半个小 ...

  8. wordpress 函数、条件判断以及文件的总结

    WordPress基本模板文件 一套完整的WordPress模板应至少具有如下文件: style.css : CSS(样式表)文件 index.php : 主页模板 archive.php : Arc ...

  9. 【重点】Shell入门教程:流程控制(2)条件判断的写法

    第三节:条件判断的写法 if条件判断中,if的语法结构中的“条件判断”可以有多种形式.测试结果是真是假,就看其传回的值是否为0. 条件测试的写法,有以下10种: 1.执行某个命令的结果 这里的命令,可 ...

随机推荐

  1. iOS弹出底部视图简单实现

    - 项目基本目录 其中xib文件用来自定义需要弹出的视图. 在主控制器里设置popview的frame等信息代码如下: 底部视图(popview)初始化放在父类视图的最顶部或者说是整个屏幕的最底部,宽 ...

  2. Fragment实现不支持左右滑动的Tab

    主要思想:顶部标题top.xml,中间Fragment,底部Tab导航. top.xml具体实现: <?xml version="1.0" encoding="ut ...

  3. [Swust OJ 585]--倒金字塔(LIS最长不下降子序列)

    题目链接:http://acm.swust.edu.cn/problem/585/ Time limit(ms): 3000 Memory limit(kb): 65535   SWUST国的一支科学 ...

  4. 提高你开发效率的十五个Visual Studio 2010使用技巧

    提高你开发效率的十五个Visual Studio 2010使用技巧 相信做开发的没有不重视效率的.开发C#,VB的都知道,我们很依赖VS,或者说,我们很感谢VS.能够对一个IDE产生依赖,说明这个ID ...

  5. USACO Prime Palindromes 构造回文数

    这道题目一点也不卡素数的判断 就是朴素的sqrt(n) 也不卡 所以~放心的用吧. 构造回文的时候看了HINT 其中是这么写的: Generate palindromes by combining d ...

  6. 多玩YY聊天记录解析全过程

    再来一发,现在开始! 下载安装YY,观察YY目录,很明显的发现了sqlite3.dll,这个数据库很多很多很多软件都在用,简单小巧且开源.删除sqlite3.dll 进入YY,历史记录不能正常显示,基 ...

  7. Python 2.7 学习笔记 异常处理

    如同别的开发语言,python也支持异常处理机制.本文介绍下它的基本语法. 一.异常的基本处理框架如下: try: 业务代码 except 异常类1: 异常处理代码 except 异常类2: 异常处理 ...

  8. Corrupted MAC on input at /usr/local/perl/lib/site_perl/5.22.1/x86_64-linux/Net/SSH/Perl/Packet.pm l

    <pre name="code" class="python">[Thu May 5 11:02:27 2016] [error] Corrupte ...

  9. 推断js中的类型:typeof / instanceof / constructor / prototype

    怎样推断js中的类型呢,先举几个样例: var a = "jason"; var b = 123; var c = true; var d = [1,2,3]; var e = n ...

  10. [置顶] c# datagridview‘s learn

    c#   一串数字“1122331111155”,要输出到DataGridview控件上,但是要逐个数字读取,如果上一个数字与下一个相同,则排成一列,不相同,则另外排成一列.如“11223311111 ...