`
qdujunjie
  • 浏览: 108710 次
  • 性别: Icon_minigender_1
  • 来自: Mars
社区版块
存档分类
最新评论

汇编语言16位随机整数填充数组代码分析(7)

阅读更多

 

 

来自于《Intel汇编语言》(第四版)第八章的一段程序。程序非常简单,以下为代码:

 

 

.data

count = 100

array WORD count DUP(?)

.code

push OFFSET array

push COUNT

call ArrayFill

 

 

ArrayFill PROC

             push ebp

             mov ebp,esp

             pushad

             mov esi,[ebp+12]             ; offset of array

             mov ecx,[ebp+8]              ; array size

             cmp ecx,0                         ; ECX < 0?

             jle L2                                ; yes : skip over loop

L1:

             mov eax,10000h              ; get random 0-FFFFh

             call RandomRange            ; from the link library

             mov [esi],eax

             add esi,TYPE WORD

             loop L1

L2:

             popad

             pop ebp

             ret 8                                 ; clean up the stack

ArrayFill ENDP

 

 

让我们来看一下代码:

 

首先定义了一个count常量和一个WORD类型(16位)的数组。

 

然后程序首先将数组的偏移地址和COUNT压入堆栈:

 

push OFFSET array

push COUNT

 

 

 

此时的堆栈框架如下图所示:

 

 

                             offset(array)       <----------     [EBP + 12]

                             count                  <----------     [EBP + 8] 

                             return address   <----------     [EBP + 4]

                             EBP                     <----------     [ EBP,ESP]

 

 

所以随后才会使用(全部相对于EBP来取地址):

 

             mov esi,[ebp+12]             ; offset of array

             mov ecx,[ebp+8]              ; array size

 

来取得数组的偏移地址和count,分别送到esi(数组游标)和ecx(数组大小)中去。

 

(保护模式下,堆栈上以4个字节为单位保存参数,所以参数的地址才分别为EBP+4,+8,+12)

 

之后的循环体中的代码主要如下:

 

             mov eax,10000h              ; get random 0-FFFFh

             call RandomRange            ; from the link library

             mov [esi],eax

             add esi,TYPE WORD

 

因为我们要为数组赋值16位随机整数,所以范围是 0到FFFFh,所以为eax中赋值10000h(1000h-1=FFFFh),之后调用作者Irvine的库函数RandomRange生成随机数,然后将此随机数放置到eax寄存器中,接着程序将此值赋值给[esi],然后esi接着移动到下一个数组元素位置。

 

这样便完成了使用16位随机整数填充数组的程序。

 

 

不过汇编语言中还有一个更方便的返回任意类型的间接操作数的偏移地址的伪指令,这就是LEA,LEA在获取堆栈参数的地址时特别有用。

 

下面的程序同样来自于《Intel汇编语言程序设计》,FillString使用随机的ASCII数字0~9来填充字符串:

 

FillString PROC USES eax  esi

      LOCAL string[20] : BYTE

      ;Create and fill a 20-bytes string with ASCII digits.

  

      lea esi , string                 ; load effective address

      mov ecx,20

L1: mov eax,10

      call RandomRange           ; AL = 0..9

      add al,30h                       ; Covert to  ASCII character

      mov [esi],al

      add esi,1

      Loop L1

      ret

FillString ENDP

 

这里使用lea方便的取得了局部数组变量的地址。

 

 

注意:string是一个间接操作数,因此下面的语句将会产生一个错误(MOV..OFFSET 只能用于直接操作数):

 

mov eax , OFFSET string           ; error

 

 

 

另外关于LEA与OFFSET,摘自原书:

LEA指令返回任意类型的间接操作数的偏移。由于间接操作数可能使用一个或多个寄存器,因此其偏移值必须在运行时计算。相反,汇编运算符OFFSET仅返回编译时的偏移常量

分享到:
评论

相关推荐

    JAVA上百实例源码以及开源项目源代码

     Java波浪文字,一个利用Java处理字符的实例,可以设置运动方向参数,显示文本的字符数组,高速文本颜色,显示字体的 FontMetrics对象,得到Graphics实例,得到Image实例,填充颜色数组数据,初始化颜色数组。...

    你必须知道的495个C语言问题

    3.2 使用我的编译器,下面的代码inti=7;printf("%d\n",i++*i++);打印出49。不管按什么顺序计算,难道不该是56吗? 3.3 对于代码inti=3;i=i++;不同编译器给出不同的i值,有的为3,有的为4,哪个是正确的? *3.4 ...

    《你必须知道的495个C语言问题》

    书中列出了C用户经常问的400多个经典问题,涵盖了初始化、数组、指针、字符串、内存分配、库函数、C预处理器等各个方面的主题,并分别给出了解答,而且结合代码示例阐明要点。 《你必须知道的495个C语言问题》结构...

    JAVA上百实例源码以及开源项目

     Java波浪文字,一个利用Java处理字符的实例,可以设置运动方向参数,显示文本的字符数组,高速文本颜色,显示字体的 FontMetrics对象,得到Graphics实例,得到Image实例,填充颜色数组数据,初始化颜色数组。...

    C++大学教程,一本适合初学者的入门教材(part2)

    6 机器语言、汇编语言和高级语言 1.7 C语言与C++的历史 1.8 C++标准库 1.9 Java、Internet与万维网 1.10 其他高级语言 1.11 结构化编程 1.12 典型C++环境基础 1.13 C++与本书的一般说明 1.14 C++编程简介 ...

    C++大学教程,一本适合初学者的入门教材(part1)

    6 机器语言、汇编语言和高级语言 1.7 C语言与C++的历史 1.8 C++标准库 1.9 Java、Internet与万维网 1.10 其他高级语言 1.11 结构化编程 1.12 典型C++环境基础 1.13 C++与本书的一般说明 1.14 C++编程简介 ...

    C语言FAQ 常见问题列表

    o 4.2 使用我的编译器,下面的代码 int i=7; printf("%d\n", i++ * i++); 返回 49?不管按什么顺序计算, 难道不该打印出56吗? o 4.3 对于代码 int i = 3; i = i++; 不同编译器给出不同的结果, 有的为 3, 有的为 4,...

    你必须知道的495个C语言问题(PDF)

    3.2 使用我的编译器,下面的代码int i=7; printf("%dnn", i++ * i++); 返回49?不管按什么顺序计算, 难道不该打印出56吗? . . . . . . 13 3.3 对于代码int i = 3; i = i++; 不同编译器给出不同的结果, 有的为 3, 有...

    易语言程序免安装版下载

     支持静态链接其它编程语言(如C/C++、汇编等)编译生成的静态库(.LIB或.OBJ),但仅限于COFF格式,支持cdecl和stdcall两种函数调用约定。  使用说明如下:函数声明和调用方法与DLL命令一致;“库文件名”以.lib...

    C++大学教程

    1.6 机器语言、汇编语言和高级语言--------------------------------------5 1.7 C语言与C++的历史--------------------------------------------------6 1.8 C++标准库--------------------------------------...

Global site tag (gtag.js) - Google Analytics