汇编语言学习笔记-分支和循环(附带作业)

概要

  1. 无条件转移
  2. 条件转移、比较指令和if结构
  3. 循环结构的实现
  4. for循环
  5. 作业

无条件转移

主要语句:

jmp StatemenLabel(自定义名字)
	代码部分
StagemenLabel:
	跳转执行部分

例子

在这里插入图片描述
在这里插入图片描述

小补充

  • 向后引用:jmp转移控制到jmp语句本身之前
  • 向前引用:jmp转移控制到jmp语句本身之后

怎么实现:jmp指令有两种指令(相对短(short),相对近(near)),它们都可以改变指令指针寄存器EIP中的值。注意是指令指针,因此,要执行的下一条指令来自于一个新的地址,而不是紧跟在当前指令后的地址。每条相对的转移指令包含相对jmp指令本身的目标位移量,这个位移量加上下一条指令的地址就是转移的目标地址(转移的目标地址=相对jmp指令的相对位移量+下一条指令的地址)。偏移量是一个有符号数。对于向前引用,它是正数,对于向后引用,它是负数。

间接转移指令:

jmp edx

使用32位地址作为目标地址,而不是位移量。但是这个地址并没有写在指令中,而是保存在寄存器中。(相关可以参照上一条博客,寻址方式

条件转移、比较指令和if结构

条件转移指令可以实现if结构、其他选择结构以及循环结构。
格式如下:

j- 目标语句#'j' = juage,'-' = 其他比较字符的缩写

等下会一一介绍,所以学好英语很重要!
解释:如果条件满足,则发生转移;否则执行下一条指令(条件转移后面的语句)。

原理

条件转移指令的原理,就是判断标志寄存器中的标识来设置的,如

jz endwhile

如果零标志ZF为1,则转移到有标号endwhile的语句,否则执行后面的语句。另外,条件转移指令不改变任何标志位,只根据已经设置好的标识符做出反应。(标识符可参照以前博客标识符

以上已经介绍了条件转移的大致原理,那么我们做到改变表示符,或者说更加符合高级语言呢?
如:

for i in range(0,100):
	print(i)

if i<10 and i>0:
	print(i)

在汇编语言中,有专门的比较操作符:
cmp
格式如下:

cmp 操作数1 操作数2

简单来说,就是使用操作数1去减操作数2(类似于sub),但是它并不会改变操作数的值(sub会),它只会根据结果改变标志位的值。参照表如下(能理解就行):
在这里插入图片描述
另外还有几个不常用的指令:

set#设置
reset#重置

它们可以设置或者清零。

紧接着,再详细说一下条件转移指令,先看下图:
在这里插入图片描述

在这里插入图片描述
是不是看着就很多?不怕怎么靠英语来记:

a:大于
b:小于
(这两个是真的没想明白,可能是无符号的原因吧)
j:juage(判断)
g:greater(大于)
n:no()
l:less(小于)
e:equal(等于)
z:zero(0)
s:sign(符号,正负)
c:carry(进位)
p:parity(奇偶)
o:overflow(溢出)

大概就是这些因为,那么我们再试一下:
jnle:开始组合,juage no less equal:判断不小于等于,则跳转,这样是不是好理解多了?

cmp和j-的组合使用

cmp eax,100
ja bigger

解释:判断eax是否大于100,是则跳转到bigger部分的指令,否则向下执行。

例子

  1. 在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

循环结构的实现

其实原理和上面一样(通过cmp,jmp实现跳转),所以直接放图:
1.
在这里插入图片描述
2.
在这里插入图片描述
3.
在这里插入图片描述

for循环

loop statementLabel

其中statementLabel是距离loop语句较短偏移量的语句标号(向前128字节或者向后127字节)
loop指令执行以下动作:

  • ECX中的值减少1
  • 如果ECX中新的值是0,那么继续执行循环指令下面的语句
  • 如果ECX中新的值不是0,那么执行转移指令到statementLabel
    -在这里插入图片描述
    同时,我们完全可以用刚刚的知识实现这个循环:
    在这里插入图片描述

作业

  1. 从键盘输入一个数字,转换成数值后,求解其绝对值,并显示结果在屏幕上。
;Program:转化
;Author:龙文汉
;Date:2020.11

.386
.MODEL FLAT

ExitProcess PROTO NEAR32 stdcall, dwExitCode:DWORD

INCLUDE io.h            ; header file for input/output

cr      EQU     0dh     ; carriage return character
Lf      EQU     0ah     ; line feed

.STACK  4096            ; reserve 4096-byte stack

.DATA                   ; reserve storage for data

number1 BYTE 100 DUP(?);
string1 BYTE "Please input the nuber",cr,Lf,0;
string2 BYTE "ABS is",cr,Lf,0;

.CODE                           ; start of main program code
_start:
    output string1;
    input number1,100;
    atoi number1;

    cmp ax,0;
    jle body;
    jmp endbody;
body:
    neg ax;
endbody:
    output string2;
    itoa number1,ax;
    output number1;


        INVOKE  ExitProcess, 0  ; exit with return code 0
PUBLIC _start                   ; make entry point public

END                             ; end of source code


  1. 键盘输入一个分数判断其属于哪个等级并显示在屏幕上,等级分别为’A’ (80-100),’B’(60-80),’C’(0-59)。例如输入 85,显示结果A在屏幕上。
;Program:算成绩等级
;Author:龙文汉
;Date:2020.11

.386
.MODEL FLAT

ExitProcess PROTO NEAR32 stdcall, dwExitCode:DWORD

INCLUDE io.h            ; header file for input/output

cr      EQU     0dh     ; carriage return character
Lf      EQU     0ah     ; line feed

.STACK  4096            ; reserve 4096-byte stack

.DATA                   ; reserve storage for data

core BYTE 10 DUP(?);
string1 BYTE "Please input the core:",cr,Lf,0;
string2 BYTE "The level is ",cr,Lf,0;

level BYTE 10 DUP(?);
.CODE                           ; start of main program code
_start:
    output string1;
    input core,10;
    atoi core;

    cmp ax,59;
    jle level_c;
    cmp ax,80;
    jle level_b;
    mov level,"A";
    jmp endbody;
level_c:
    mov level,"C";
    jmp endbody;
level_b:
    mov level,"B";
    jmp endbody;
endbody:
    output level;


        INVOKE  ExitProcess, 0  ; exit with return code 0
PUBLIC _start                   ; make entry point public

END                             ; end of source code


  1. 求1+2+3+…+99+100的值,并显示结果在屏幕上。
;Program:循环求值
;Author:龙文汉	
;Date:2020.11

.386
.MODEL FLAT

ExitProcess PROTO NEAR32 stdcall, dwExitCode:DWORD

INCLUDE io.h            ; header file for input/output

cr      EQU     0dh     ; carriage return character
Lf      EQU     0ah     ; line feed

.STACK  4096            ; reserve 4096-byte stack

.DATA                   ; reserve storage for data

num BYTE 100 DUP(?);
string1 BYTE "The answer is:",cr,Lf,0;

.CODE                           ; start of main program code
_start:
    mov ax,1;
    mov bx,0;
whilesum:
    cmp ax,100;
    jle body;
    jmp endbody;
body:
    add bx,ax;
    inc ax;
    jmp whilesum;
endbody:
    output string1;
    itoa num,bx;
    output num;

        INVOKE  ExitProcess, 0  ; exit with return code 0
PUBLIC _start                   ; make entry point public

END                             ; end of source code


  1. 附加题:题目:计算给定数字的平方、立方值

实验要求:从键盘输入0至9中任一自然数x,求其立方值。若输入的字符不是0至9之间的数字,则显示错误信息,并要求重新输入。要求有信息提示输入数字、显示计算结果和提示输入错误。

提示:用户输入字符首先判断是否是0至9之间的字符,如果是,则转换为整数并计算其立方值,然后显示结果;如果不是,则显示输入错误信息并等待用户重新输入。

例如输入数字为 4,则显示

数值 平方 立方

1 1 1

2 4 8

3 9 27

4 16 64

;Program:
;Author:
;Date:

.386
.MODEL FLAT

ExitProcess PROTO NEAR32 stdcall, dwExitCode:DWORD

INCLUDE io.h            ; header file for input/output

cr      EQU     0dh     ; carriage return character
Lf      EQU     0ah     ; line feed

.STACK  4096            ; reserve 4096-byte stack

.DATA                   ; reserve storage for data

string1 BYTE "Please input the number(0-9):",cr,Lf,0;
string2 BYTE "The number is false,please input the correct number(0-9):",cr,Lf,0;
string3 BYTE "squera",cr,Lf,0;
string4 BYTE cr,Lf,"cube:",cr,Lf,0;

cube BYTE 100 DUP(?),cr,Lf,0;
squera BYTE 100 DUP(?),cr,Lf,0;
number BYTE 100 DUP(?),cr,Lf,0;
answer BYTE 100 DUP(?),cr,Lf,0;

.CODE                           ; start of main program code
_start:
body:
    output string1;
    input number,100;
    atoi number;
    cmp ax,0;
    jl falsebody;
    cmp ax,9;
    jg falsebody;
    jmp mainbody;
falsebody:
    output string2;
    jmp body;
mainbody:
    output string3;
    mov cx,ax;
    mul ax;
    itoa answer,dx;
    output answer;
    itoa answer,ax;
    output answer;

    output string4;
    mov ax,cx;
    mul ax;
    mul cx;
    itoa answer,dx;
    output answer;
    itoa answer,ax;
    output answer;


        INVOKE  ExitProcess, 0  ; exit with return code 0
PUBLIC _start                   ; make entry point public

END                             ; end of source code


待更新…

  • 4
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Hanzoe_lwh

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值