▶ 书中第七章的程序,使用各种位移运算,加深了对内存、寄存器中整数类型变量存储的认识

● 代码,双字数组右移 4 位

 INCLUDE Irvine32.inc

 COUNT =                            ; 右移位数

 .data
array DWORD 148B2165h, 8C943A29h, 6DFA4B86h, 91F76C04h, 8BAF9857h .code
main PROC
mov esi, OFFSET array ; 移之前的情况
mov ecx, LENGTHOF array
mov ebx, TYPE array
call DumpMem mov bl, COUNT
call ShiftDoublewords mov esi, OFFSET array ; 移之后的情况
mov ecx, LENGTHOF array
mov ebx, TYPE array
call DumpMem call WaitMsg
exit
main ENDP ShiftDoublewords PROC
mov esi, OFFSET array
mov ecx, (LENGTHOF array) - ; 循环次数等于数组长度减一,最后一个数单独处理 L1:
push ecx ; 需要使用 cl 移动数
mov cl, COUNT
mov eax, [esi + TYPE DWORD] ; 下一个数字 DWORD 移入 eax
shrd [esi], eax, cl ; eax 逐渐移入当前数字 push esi ; 移了 4 位,显示一下
push ecx
push ebx
mov esi, OFFSET array
mov ecx, LENGTHOF array
mov ebx, TYPE array
call DumpMem
pop ebx
pop ecx
pop esi add esi, TYPE DWORD ; 移完了,esi 指向下一个数字
pop ecx ; 恢复 ecx
loop L1 shr DWORD PTR [esi], COUNT ; 最后一个数,直接右移,偷偷使用 cf 中的值 ret
ShiftDoublewords ENDP END main

● 输出结果

Dump of offset                              // 移之前
-------------------------------
148B2165 8C943A29 6DFA4B86 91F76C04 8BAF9857 Dump of offset // 移第 1 个 DWORD,"9" 来自第二个数的最低 4 位
-------------------------------
9148B216 8C943A29 6DFA4B86 91F76C04 8BAF9857 Dump of offset // 移第 2 个 DWORD
-------------------------------
9148B216 68C943A2 6DFA4B86 91F76C04 8BAF9857 Dump of offset // 移第 3 个 DWORD
-------------------------------
9148B216 68C943A2 46DFA4B8 91F76C04 8BAF9857 Dump of offset // 移第 4 个 DWORD
-------------------------------
9148B216 68C943A2 46DFA4B8 791F76C0 8BAF9857 Dump of offset // 移第 5 个 DWORD,完成移动
-------------------------------
9148B216 68C943A2 46DFA4B8 791F76C0 08BAF985

● 代码,内存右移 1 位

 INCLUDE Irvine32.inc

 .data
array BYTE 45h, 67h, 89h .code
main PROC
call DisplayArray mov esi,
mov eax, OFFSET array
shr array[esi+], ; 最高字节(第一个元素/字节)右移
rcr array[esi+], ; 中间元素循环右移,偷偷使用 CF
rcr array[esi], ; 最低字节循环右移 call DisplayArray call WaitMsg
exit
main ENDP DisplayArray PROC
pushad mov esi, OFFSET array ; 先用 DumpMem 显示内存情况(注意元素/字节是倒着存的)
mov ecx, LENGTHOF array
mov ebx, TYPE array
call DumpMem mov esi, LENGTHOF array ; esi 循环变量
dec esi
L1:
mov al, array[esi]
mov ebx,
call WriteBinB ; display binary bits
mov al, ' '
call WriteChar
dec esi
Loop L1 call Crlf
popad
ret
DisplayArray ENDP END main

● 输出结果

Dump of offset 00F66000         // 右移前,注意元素/字节是顺着存的
------------------------------- // 用 DumpMem 显示反而会翻转过来 Dump of offset 00F66000 // 右移后
-------------------------------
A2 B3

● 代码,二进制数转 ASCII 显示(逐字节打印),结果输出 00010010001101001010101111001101

 INCLUDE Irvine32.inc

 .data
binVal DWORD 1234ABCDh ; 需要输出的数字
buffer BYTE dup(), .code
main PROC
mov eax, binVal
mov esi, OFFSET buffer
call BinToAsc mov edx,OFFSET buffer
call WriteString call Crlf
call WaitMsg
exit
main ENDP BinToAsc PROC uses ecx esi mov ecx, L1:
shl eax, ; eax 中的二进制串左移一位,最高位放入 cf 用于下面的跳转
; binVal 在内存中存成了 cd ab 34 12(4 字节整数模式下可以看到 1234abcd)
; 但对寄存器进行左移的时候还是按照 1234ABCDh 来左移
; 例如第一次左移后得到 2469579Ah
mov BYTE PTR [esi],'' ; 内存先写上 '0' 再说
jnc L2 ; 如果 cf 中是 1,把内存改写成 '1',否则跳过改写
mov BYTE PTR [esi],'' L2:
inc esi
loop L1 ret
BinToAsc ENDP END main

● 代码,用 adc 指令实现长整数加法

 INCLUDE Irvine32.inc

 .data
op1 BYTE 34h,12h,98h,74h,06h,0A4h,0B2h,0A2h
op2 BYTE 02h,45h,23h,00h,00h, 87h,10h, 80h sum BYTE dup() ; = 0122C32B0674BB5736h .code
main PROC mov esi, OFFSET op1
mov edi, OFFSET op2
mov ebx, OFFSET sum
mov ecx, LENGTHOF op1 call Extended_Add mov esi, OFFSET sum
mov ecx, LENGTHOF sum add esi, ecx ; 找到数组结尾,从高位逐字节输出
sub esi, TYPE BYTE
mov ebx, TYPE BYTE L1:
mov al,[esi]
call WriteHexB
sub esi, TYPE BYTE
loop L1 call Crlf
call WaitMsg
exit
main ENDP Extended_Add PROC
pushad
clc ; 清除 CF mov edx,
L1:
mov al, [esi]
adc al, [edi]
pushfd ; CF(进位标志)压栈
mov [ebx], al
add esi, ; 更新指针
add edi,
add ebx,
popfd ; CF 出栈,准备进行下一次加法
loop L1 mov byte ptr [ebx], ; 最后一次加法,最高字节加上剩余的进位标志
adc byte ptr [ebx], popad
ret
Extended_Add ENDP END main

● ASCII 长整数加法,结果输出 1000525533291780

 INCLUDE Irvine32.inc

 DECIMAL_OFFSET =                       ; 小数点位于位 5 的右边(没用到)
.data
decimal_one BYTE "" ; == 1001234567.89765
decimal_two BYTE "" ; == 9004020765.02015
sum BYTE (SIZEOF decimal_one + ) DUP(), ; 预留进位 .code
main PROC
mov esi, SIZEOF decimal_one - ; 从最低位开始
mov edi, SIZEOF decimal_one
mov ecx, SIZEOF decimal_one
mov bh, ; 旧进位标志,初始化为 0 L1:
mov ah,
mov al, decimal_one[esi]
add al, bh ; 加旧进位
aaa ; 调整和
mov bh, ah ; ah 存储了进位,将其放进 bh
or bh, 30h ; 转成 ASCII
add al, decimal_two[esi] ; 加一个数字,过程同上
aaa
or bh, ah ; 9 + 1 + 9 = 19 < 20,加了两次但最多进位 1
or bh, 30h ; 进位和结果都转成 ASCII
or al, 30h
mov sum[edi], al ; 当前位结果放入内存
dec esi ; 指向下一对计算的数字
dec edi
loop L1
mov sum[edi], bh ; 最后的进位放在预留的最高位上 mov edx, OFFSET sum
call WriteString
call Crlf
call WaitMsg
exit
main ENDP
END main

● 压缩十进制加法,输出结果 00011743。逻辑简单,但是不能理解 daa 的实现方法

 INCLUDE Irvine32.inc

 .data
packed_1 WORD 4536h
packed_2 WORD 7207h
sum DWORD ? .code
main PROC
mov sum,
mov esi,
mov eax, mov al,BYTE PTR packed_1[esi] ; 低字节,daa 将 al 中的和转化为十进制和的低两位,放入内存
add al,BYTE PTR packed_2[esi]
daa
mov BYTE PTR sum[esi],al inc esi ; 中字节,包含进位
mov al,BYTE PTR packed_1[esi]
adc al,BYTE PTR packed_2[esi]
daa
mov BYTE PTR sum[esi],al inc esi ; 高字节,只考虑进位
mov al,
adc al,
mov BYTE PTR sum[esi],al mov eax,sum
call WriteHex
call Crlf
call WaitMsg
exit
main ENDP
END main

《汇编语言 基于x86处理器》第七章整数运算部分的代码的更多相关文章

  1. 《汇编语言 基于x86处理器》第九章字符串与数组部分的代码

    ▶ 书中第九章的程序,主要讲了字符串相关的输入.输出,以及冒泡排序.二分搜索 ● 代码,Irvine32 中的字符串库函数代码范例 INCLUDE Irvine32.inc .data str1 BY ...

  2. 《汇编语言 基于x86处理器》第八章高级过程部分的代码 - 两种规范计算数组元素的和

    ▶ 输入 Count 个 32 位有符号整数,计算他们的和 ● 代码,使用堆栈传参 ;// Sum_main.asm,主过程 INCLUDE Irvine32.inc EXTERN PromptFor ...

  3. 《汇编语言 基于x86处理器》第十三章高级语言接口部分的代码 part 2

    ▶ 书中第十三章的程序,主要讲了汇编语言和 C/++ 相互调用的方法 ● 代码,汇编中调用 C++ 函数 ; subr.asm INCLUDE Irvine32.inc askForInteger P ...

  4. 《汇编语言 基于x86处理器》前五章的小程序

    ▶ 书中前五章的几个小程序,基本的运算操作,使用了作者的库 Irvine32 和 Irvine64(一开始以为作者网站过期了,各网站上找到的文件大小都不一样,最后发现是要搭梯子 Orz,顺利下载).注 ...

  5. 《汇编语言 基于x86处理器》第十一章 MS-DOS 编程部分的代码 part 2

    ▶ 书中第十一章的程序,主要讲了 Windows 接口,在小黑框中进行程序交互 ● 在屏幕指定位置输出带自定义属性的文字 INCLUDE Irvine32.inc .data outHandle HA ...

  6. 《汇编语言 基于x86处理器》第十二章浮点数部分的代码

    ▶ 书中第十二章的程序,主要讲了 FPU 的指令和浮点数计算的过程 ● 代码,简单的 32 为浮点数测试 INCLUDE Irvine32.inc INCLUDE macros.inc .data f ...

  7. 《汇编语言 基于x86处理器》第六章条件处理部分的代码

    ▶ 书中第六章的程序,使用了条件判断和跳转来实现一些功能 ● 代码,查找数组首个非零值 INCLUDE Irvine32.inc .data intArray SWORD , , , , , , , ...

  8. 《汇编语言 基于x86处理器》第十章 - 运行一个 16位实地址汇编程序

    ▶ 书上第 10 章,主要讲了宏,引用了一个 16 位实地址的程序,从代码开始到运行 ● 代码 ; main.asm INCLUDE Macros.inc IF IsDefined( RealMode ...

  9. 《汇编语言 基于x86处理器》第十章结构和宏部分的代码

    ▶ 书中第十章的程序,主要讲了结构与宏的使用 ● 代码,使用结构,对比是否对齐的性能差距 INCLUDE Irvine32.inc INCLUDE macros.inc structN STRUCT ...

随机推荐

  1. 关于libusb-win32开发的经验

    引用:http://blog.sina.com.cn/s/blog_4b4b54da010153zb.html 作为设备开发者, 一般需要让设备与上位机PC通讯, 我们往往考虑采用以下几种接口: rs ...

  2. linux du 查看文件及文件夹大小

    1.查看当前目录大小: 如在:/home/jzw/share/ du -sh 1.6G    . 2.查看当前目录下各个文件夹的大小: 如在:/home/jzw/share/ du -sh * 3.6 ...

  3. sql语句事务

    set xact_abort on begin tran ... commit tran

  4. Tomcat实战-调优方案

    Tomcat的默认配置,性能并不是最优的,可以通过优化tomcat以此来提高网站的并发能力.提高Tomcat的性能可以分为两个方向. 服务器资源 服务器所能提供CPU.内存.硬盘的性能对处理能力有决定 ...

  5. 组合(composite)模式

    定义 将对象组合成树形结构以表示“部分-整体”的层次结构,使得用户对单个对象和组合对象的使用具有一致性 组合模式(Composite)将小对象组合成树形结构,使用户操作组合对象如同操作一个单个对象.组 ...

  6. P1601高精度加法

    传送门 虽然本题一本通上有,但是一本通不是万能的,这道题就漏掉了进位(所以这告诉我们加法进位很重要) 直接上修改后的题解 #include<iostream> #include<cs ...

  7. 弹性势能,position,min用法,获取元素的宽

    弹性势能: 网页div移动的mousemove的次数,跟div移动的距离没有关系,跟鼠标移动的快慢有关,浏览器自身有个计数事件,几毫秒 _this.seed*=0.95 //摩擦系数的写法 posit ...

  8. iOS 结构化数据访问

    一.介绍 在存储大量数据时,除了最基本的打开文件,读取文件,存盘等这些没有明确管理机制的方式来存储数据外,iOS还提供了另外几种重要的数据存储方式.虽然这些方式最后还是将数据存储在文件中,但是iOS以 ...

  9. unity3d简介

    一.介绍: Unity3D软件:综合开发环境,实时三维动画等类型的多媒体内容,并支持这些内容在Windows.iOS.Android等多种平台的发布. Mono:脚本编程基于Mono技术,可使用Jav ...

  10. Hadoop 2.x常用端口及查看方法

    Hadoop集群的各部分一般都会使用到多个端口,有些是daemon之间进行交互之用,有些是用于RPC访问以及HTTP访问.而随着Hadoop周边组件的增多,完全记不住哪个端口对应哪个应用,特收集记录如 ...