MASM 有许多循环伪指令用于生成重复的语句块:WHILE、REPEAT、FOR 和 FORC。与 LOOP 指令不同,这些伪指令只在汇编时起作用,并使用常量值作为循环条件和计数器:

WHILE 伪指令根据一个布尔表达式来重复语句块。

REPEAT 伪指令根据计数器的值来重复语句块。

FOR 伪指令通过遍历符号列表来重复语句块。

FORC 伪指令通过遍历字符串来重复语句块。

WHILE 伪指令

WHILE 伪指令重复一个语句块,直到特定的常量表达式为真。其语法如下:

WHILE constExpression

statements

ENDM

下面的代码展示了如何在 1 到 F000 0000h 之间生成斐波那契 (Fibonacci) 数,作为汇编时常数序列:

.data

val1 = 1

val2 = 1

DWORD val1 ;前两个值

DWORD val2

val3 = val1 + val2

WHILE val3 LT 0F0000000h

DWORD val3

val1 = val2

val2 = val3

val3 = val1 + val2

ENDM

REEPEAT 伪指令

在汇编时,REPEAT 伪指令将一个语句块重复固定次数。其语法如下:

REPEAT constExpression

statements

ENDM

constExpression 是一个无符号整数常量表达式,用于确定重复次数。

在创建数组时,REPEAT 的用法与 DUP 类似。在下面的例子中,WeatherReadings 结构含有一个地点字符串和一个包含了降雨量与湿度读数的数组:

WEEKS_PER_YEAR = 52

WeatherReadings STRUCT

location BYTE 50 DUP(0)

REPEAT WEEKS_PER_YEAR

LOCAL rainfall, humidity

rainfall DWORD ?

humidity DWORD ?

ENDM

WeatherReadings ENDS

由于汇编时循环会对降雨量和湿度重定义,使用 LOCAL 伪指令可以避免因其导致的错误。

FOR 伪指令

FOR 伪指令通过迭代用逗号分隔的符号列表来重复一个语句块。列表中的每个符号都会引发循环的一次迭代过程。其语法如下:

FOR parameter,

statements

ENDM

第一次循环迭代时,parameter 取 arg1 的值,第二次循环迭代时,parameter 取 arg2 的值; 以此类推,直到列表的最后一个实参。

【示例】现在创建一个学生注册的场景,其中,COURSE 结构含有课程编号和学分值;SEMESTER 结构包含一个有 6 门课程的数组和一个计数器 NumCourses:

COURSE STRUCT

Number BYTE 9 DUP(?)

Credits BYTE ?

COURSE ENDS

;semester 含有一个课程数组。

SEMESTER STRUCT

Courses COURSE 6 DUP(<>)

NumCourses WORD ?

SEMESTER ENDS

使用 FOR 循环可以定义 4 个 SEMESTER 对象,每一个对象都从由尖括号括起的符号列表中选择一个不同的名称:

.data

FOR semName,

semName SEMESTER <>

ENDM

如果查看列表文件就会发现如下变量:

.data

Fall2013 SEMESTER <>

Spring2014 SEMESTER <>

Summer2014 SEMESTER <>

Fall2014 SEMESTER <>

FORC 伪指令

FORC 伪指令通过迭代字符串来重复一个语句块。字符串中的每个字符都会引发循环的一次迭代过程。其语法如下:

FORC parameter,

statements

ENDM

第一次循环迭代时,parameter 等于字符串的第一个字符,第二次循环迭代时,parameter 等于字符串的第二个字符;以此类推,直到最后一个字符。

下面的例子创建了一个字符查找表,其中包含了一些非字母字符。注意,< 和 > 的前面必须有文字字符(!)运算符,以防它们违反FORC伪指令的语法:

Delimiters LABEL BYTE

FORC code, >

BYTE "&code"

ENDM

生成的数据表如下所示,可以在列表文件中查看:

00000000  40  1  BYTE  "@"

00000001  23  1  BYTE  "#"

00000002  24  1  BYTE  "$"

00000003  25  1  BYTE  "%"

00000004  5E  1  BYTE  "^"

00000005  26  1  BYTE  "&"

00000006  2A  1  BYTE  "*"

00000007  3C  1  BYTE  "

00000008  3E  1  BYTE  ">"

示例:链表

结合结构声明与 REPEAT 伪指令以指示汇编器创建一个链表的数据结构是相当简单的。链表中的每个节点都含有一个数据域和一个链接域:

在数据域中,一个或多个变量可以保存每个节点所特有的数据。在链接域中,一个指针包含了链表下一个节点的地址。最后一个节点的链接域通常是一个空指针。现在编写程序创建并显示一个简单链表。首先,程序定义一个节点,其中含有一个整数(数据)和一个指向下一个节点的指针:

ListNode STRUCT

NodeData DWORD ?    ;节点的数据

NextPtr DWORD ?        ;指向下一个节点的指针

ListNode ENDS

接着 REPEAT 伪指令创建了 ListNode 对象的多个实例。为了便于测试,NodeData 域含有一个整数常量,其范围为 1〜15,在循环内部,计数器加 1 并将值插入到 ListNode 域:

TotalNodeCount = 15

NULL = 0

Counter = 0

.data

LinkedList LABEL PTR ListNode

REPEAT TotalNodeCount

Counter = Counter + 1

ListNode

ENDM

表达式 ($+Counter*SIZEOF ListNode) 告诉汇编器把计数值与 ListNode 的大小相乘,并将乘积与当前地址计数器相加。结果值插入结构内的 NextPtr 域。[注意一个有趣的现象:位置计数器的值 ($) 固定在表的第一节点上。]该表用尾节点 (tail node) 来标记末尾,其 NextPtr 域为空 (0):

ListNode <0,0>

当程序遍历该表时,它用下面的语句检索 NextPtr 域,并将其与 NULL 比较,以检查是否为表的末尾:

mov eax,(ListNode PTR [esi]).NextPtr

cmp eax,NULL

程序清单

完整的程序清单如下所示。在 main 中,一个循环遍历链表并显示全部的节点值。与使用固定计数值控制循环相比,程序检查是否为尾节点的空指针,若是则停止循环:

; 创建一个链表 (List.asm)

INCLUDE Irvine32.inc

ListNode STRUCT

NodeData DWORD ?

NextPtr DWORD ?

ListNode ENDS

TotalNodeCount = 15

NULL = 0

Counter = 0

.data

LinkedList LABEL PTR ListNode

REPT TotalNodeCount

Counter = Counter + 1

ListNode

ENDM

ListNode <0,0> ; tail node

.code

main PROC

mov esi,OFFSET LinkedList

; 显示 NodeData 域的值

NextNode:

; 检查是否为尾节点

mov eax,(ListNode PTR [esi]).NextPtr

cmp eax,NULL

je quit

; 显示节点数据

mov eax,(ListNode PTR [esi]).NodeData

call WriteDec

call Crlf

; 获取下一个节点的指针

mov esi,(ListNode PTR [esi]).NextPtr

jmp NextNode

quit:

exit

main ENDP

END main

C语言REPEAT程序,汇编语言定使用WHILE、REPEAT、FOR 和 FORC伪指令定义重复语句块相关推荐

  1. python语言语句块标记是_Python的基本语法——语句块

    1.语句块是在条件为真(条件语句)时执行或者执行多次(循环语句)的一组语句: 2在代码前放置空格来缩进语句即可创建语句块,语句块中的每行必须是同样的缩进量: 3.缩进:Python开发者有意让违反了缩 ...

  2. c语言延时系统,基于VB的单片机C语言延时程序各参数计算系统

    仪器仪表用户 doi:10.3969/j.issn.1671-1041.2011.04.013 □科研设计成果□ 基于VB的单片机C语言延时程序各参数计算系统 刘 1 锋,林 奕 2 (1.武汉理工大 ...

  3. 语言翻译成汇编语言_学习编程有没有必要从C语言和C++学起?应该怎么学?

    硬件层级:这里也就是实体硬件,包括:CPU.内存.显卡等等...这些都不属于软件的范畴内. 汇编层级:在之前没有C/C++以及java之前,是汇编的年代.那么汇编语言对于我们来说,可读性是很查的,不适 ...

  4. 2020蓝桥杯省赛---java---B---5( REPEAT 程序)

    题目描述 [问题描述]附件 prog.txt 中是一个用某种语言写的程序.其中 REPEAT k 表示一个次数为 k 的循环.循环控制的范围由缩进表达,从次行开始连续的缩进比该行多的(前面的空白更长的 ...

  5. 【初涉C语言】程序员欢迎来到C语言的世界!

    计算机发展史 机器语言 所有的代码里面只有0和1 优点:直接对硬件产生作用,程序的执行效率非常高 缺点:指令又多又难记.可读性差.无可移植性 汇编语言 符号化的机器语言,用一个符号(英文单词.数字)来 ...

  6. C语言/C++程序员大神打造纯C的电子时钟(加图形库+源码)

    C语言/C++程序员大神打造纯C的电子时钟,每天看时间再也不麻烦了 C和C++的区别: C是一个结构化语言,它的重点在于算法和数据结构.C程序的设计首要考虑的是如何通过一个过程,对输入(或环境条件)进 ...

  7. c语言高级程序知识,《高级语言程序设计》知识点总结(一)

    <高级语言程序设计>知识点总结(一) 分类:自考 | 更新时间:2016-07-07| 来源:中华网教育 1.1 程序设计和程序设计语言 1.程序 从最一般的意义来说,程序是对解决某个计算 ...

  8. 【题解】2020年蓝桥杯C/C++程序设计B组·试题 D: REPEAT 程序

    欢迎光临大千小熊的博客,我是一只又会MMD又会C++的正派熊,B站和CSDN同步更新,欢迎关注. 题目背景说明: 这是一道2020年蓝桥杯C/C++程序设计B组·省级比赛的题目.题目难度不高,主要是想 ...

  9. c语言串口程序编写,用C语言编写串口程序

    在当今,流行的编程软件种类繁多,它们编程方便.易于维护,但是在与硬 件直接打交道和编制系统软件时却束手无策,于是C语言就有了用武之地.C语言 作为汇编语言与高级语言之间的一种过渡语言,兼有汇编语言的高 ...

最新文章

  1. python类库丰富吗_Rich库:丰富你的Python程序终端输出
  2. C# 实现DB文件的导入导出功能
  3. MyBatis关键配置
  4. 回溯算法背包问题迭代c语言,回溯法解决0_1背包问题(迭代和递归)
  5. 大咖布道丨证券行业规模化敏捷和核心能力演进
  6. Asp.net2.0动态加载用户控件的三种方法
  7. 05_流与文件——课后作业
  8. Windows Server 2012 R2 服务器管理器介绍和配置使用
  9. 深入理解JAVA虚拟机大全
  10. Decorate 模式
  11. 【转】专家:制造业将大批死亡 都怪马云
  12. border设置1px看起来很粗问题
  13. Ubuntu用C/C++在终端打印不同颜色的字体
  14. SpringBoot导入导出你会用吗?(EasyPoi)
  15. 如何调用股票交易软件api接口?
  16. configure: error: C++ preprocessor /lib/cpp fails sanity check
  17. 为什么很多人工作都不开心?(转)
  18. 古今之成大事业、大学问者,必经过三种之境界
  19. 多个Excel根据两个同指标进行合并查询,处理。
  20. 全球未来网络与SDN技术大会5月18日拉开帷幕

热门文章

  1. A Survey for Image Quality Assessment(综述)
  2. 【微信小程序——云音乐播放器】
  3. mysql关系图查看
  4. Spring Boot 升级所遇到的坑们s 1.5.x升级到2.1.x
  5. X86 将死?RISC-V 正当立
  6. JavaScript DOM加强(佟刚)
  7. CAD高低版本互转,版本转换知识
  8. NB-IOT修改KV值的方法
  9. STM32F4的DSP库
  10. [精]Oracle 内存结构详解