《汇编语言基础教程》 学习实录

  • 第3章 算术运算指令
  • 第4章 选择结构
  • 第5章 迭代结构
  • 第6章 逻辑运算指令、移位指令、循环移位指令和堆栈

书目:《Guide to assembly language. A concise introduction》 by James T.Streib

时间紧迫,这里仅记录我学习过程中写的一些示例代码,每个示例代码都有对应C语言版本。长时间不用难免忘记,希望能通过一些简单示例快速拾起intel汇编语法。

IDE:VS2017
Intel x86汇编环境搭建与配置

第3章 算术运算指令

COMMENT @
#include<stdio.h>
int main(){int volts, ohms, amperes;printf("\n%s","Enter the number of volts: ");scanf("%d", &volts);printf("%s","Enter the number of ohms: ");scanf("%d", &ohms);amperes = volts / ohms;printf("\n%s%d\n\n", "The number of amperes is:", amperes);
}
@.386
.model flat, C
.stack 100hincludelib       msvcrt.libprintf    proto   arg1:Ptr Byte,  printlist:VARARG
scanf   proto   arg1:Ptr Byte,  printlist:VARARG.data
volts   SDWORD  ?
ohms    SDWORD  ?
amperes SDWORD  ?in1fmt Byte "%d",0
msg1fmt Byte 0Ah,"%s",0
msg2fmt Byte "%s",0
msg3fmt Byte 0Ah,"%s%d",0Ah,0Ah,0msg1 Byte "Enter the number of volts: ",0
msg2    Byte "Enter the number of ohms: ",0
msg3    Byte "The number of amperes is:",0
.code
start1:INVOKE printf, ADDR msg1fmt, ADDR msg1INVOKE scanf, ADDR in1fmt, ADDR voltsINVOKE printf, ADDR msg2fmt, ADDR msg2INVOKE scanf, ADDR in1fmt, ADDR ohmsmov eax, voltscdqidiv ohmsmov amperes, eaxINVOKE printf, ADDR msg3fmt,ADDR msg3, amperesret
end start1

第4章 选择结构

COMMENT @ C语言表述#include<stdio.h>int main(){int voltage;printf("%s", "Enter an AC Voltage: ");scanf("%d", &voltage);if (voltage >= 110 && voltage <= 120)printf("\n%s\n", "Voltage is Acceptable");else {printf("\n%s\n", "Warning!");if(voltage < 110)printf("%s\n", "Voltage too Low");elseprintf("%s\n", "Voltage too High");}if(voltage >=380)printf("%s", "Generator power off...");printf("\n");return 0; }
@
; 以下是上述C代码的汇编语言表述
; MASM32 intelx86 Debugger
; =============================================.listall.386.model flat, c.stack 100h
includelib msvcrt.lib
scanf   PROTO   :PTR Byte, :VARARG
printf  PROTO   :PTR Byte, :VARARG.data
in1fmt  Byte    "%d",0msg1fmt Byte    "%s",0
msg1    Byte    "Enter an AC Voltage: ",0
msg2fmt Byte    0Ah,"%s",0Ah,0
msg2    Byte    "Voltage is Acceptable",0
msg3    Byte    "Warning!",0
msg3fmt Byte    "%s",0Ah,0
msg4    Byte    "Voltage too Low",0
msg5    Byte    "Voltage too High",0
msg4fmt Byte    0Ah,0
msg6    Byte    "Generator power off...",0voltage SDWORD  ?.code
main    PROCINVOKE printf, ADDR msg1fmt, ADDR msg1INVOKE scanf, ADDR in1fmt, ADDR   voltage
if01:       cmp voltage, 110jl  else01cmp   voltage, 120jg  else01
then01:     INVOKE printf, ADDR msg2fmt, ADDR msg2jmp   endif01
else01:     nopINVOKE printf, ADDR msg2fmt, ADDR msg3
if02:       cmp voltage, 110jge else02
then02:     INVOKE printf, ADDR msg3fmt, ADDR msg4jmp endif02else02:        INVOKE printf, ADDR msg3fmt, ADDR msg5endif02:  nopendif01: nop.if voltage >= 380INVOKE printf, ADDR msg1fmt, ADDR msg6nop    ;这里要有一个补位的,否则会抛出未知异常.endifINVOKE   printf, ADDR msg4fmtret
main    ENDPEND main

第5章 迭代结构

  1. INVOKE指令破坏寄存器eax、ecx和edx的值,故用ecx计数时需要用到一个内存变量存储计数值

  2. loop指令使用时ecx的值不能为0或负值

  3. 完整代码示例:实现幂函数

COMMENT @
#include<stdio.h>int main() {int x, n, i, ans;printf("%s", "Enter x: ");scanf_s("%d", &x);printf("%s", "Enter n: ");scanf_s("%d", &n);if (x < 0 || n < 0)printf("\n%s\n\n", "Error: Negative x and/or y");elseif (x == 0 && n == 0)printf("\n%s\n\n", "Error: Undefined answer");else {i = 1;ans = 1;while (i <= n) {ans = ans * x;++i;}printf("\n%s%d\n\n", "The answer is: ", ans);}return 0;
}
@.listall.386.model flat, c.stack 100hincludelib msvcrt.libprintf  PROTO :Ptr Byte, :VARARG
scanf   PROTO :Ptr Byte, :VARARG.data
x       SDWORD  ?
n       SDWORD  ?
i       SDWORD  ?
ans     SDWORD  ?msg1fmt    Byte    "%s",0
msg2fmt Byte    0Ah,"%s",0Ah,0Ah,0
msg3fmt Byte    0Ah,"%s%d",0Ah,0Ah,0in1fmt    Byte    "%d",0msg1    Byte    "Enter x: ",0
msg2    Byte    "Enter n: ",0
msg3    Byte    "Error: Negative x and/or y",0
msg4    Byte    "Error: Undefined answer",0
msg5    Byte    "The answer is: ",0.codemain  PROCINVOKE printf, ADDR msg1fmt, ADDR msg1INVOKE scanf, ADDR in1fmt, ADDR xINVOKE printf, ADDR msg1fmt, ADDR msg2INVOKE scanf, ADDR in1fmt, ADDR nif01: cmp x, 0jge else01
OR01:   cmp n, 0jge else01
then01: nopINVOKE printf, ADDR msg2fmt, ADDR msg3
else01: nopif02:    cmp x, 0jne else02cmp n, 0jne else02
then02: nopINVOKE printf, ADDR msg2fmt, ADDR msg4
else02: nopmov i, 1mov ans, 1mov ecx, i
w01:    cmp ecx, njg    endw01mov eax, ansimul xmov ans, eaxinc ecxjmp w01
endw01: nopmov i, ecxINVOKE printf, ADDR msg3fmt, ADDR msg5, ans
endif02: nopendif01:nopret
main    ENDPEND     main

第6章 逻辑运算指令、移位指令、循环移位指令和堆栈

  1. 逻辑运算:and \ or \ xor A, B

  2. 逻辑移位:左shl \ shr A, B

  3. 测试比特位:test A, B A值不变 || and A, B,A值会变

  4. 算术移位:左sal A, B\ sar A, B 右,salshl完全一样,但sarshr不一样,考虑负数的情况即可

  5. 循环移位:左rol A, B \ ror A, B右,一般移动一整轮使得值复原

  6. 堆栈:push reg\mem\imm; pop reg\mem; 注意:①只能16位或32位寄存器/内存空间可使用;②pop不能取立即数

    堆栈应用:排序算法中的交换值
    方法一 (较慢)          方法二: 中等             方法三:较快

    push num1           mov eax, num1           mov eax, num1
    push num2           xchg eax, num2          mov edx, num2
    pop num1            mov num1, eax           mov num1, edx
    pop num2                                    mov num2, eax
    

    原因:指令执行速度 mov > xchg > push/pop,但从方法一到方法三,使用的寄存器数分别为0、1、2,所以折中考虑方法二

  7. 章节实例:模拟OCR设备,检测文档状态字节(每一位都代表一个状态)

    COMMENT @bit     ERROR STATE0      SHORT DOCUMENT1      LONG DOCUMENT2      CLOSE FEED3     MULTIPLE FEED4      EXCESSIVE SKEW5     DOCUMENT MISFEED6       DOCUMENT JAM7       UNSPECIFIED ERROR@.listall.386.model flat,stdcall.stack 100hincludelib msvcrt.libprintf    PROTO C :PTR Byte, :VARARG
    scanf   PROTO C :PTR Byte, :VARARG.data
    msg1fmt     Byte    "%s",0
    in1fmt      Byte    "%x",0
    msg2fmt     Byte    "%s%x",0Ah,0Ah,0
    msg1        Byte    0Ah,"Enter a hexadecimal number: ",0
    msg2        Byte    "The hexadecimal number is: ",0
    msgshort    Byte    "SHORT DOCUMENT",0Ah,0
    msglong     Byte    "LONG DOCUMENT",0Ah,0
    msgclose    Byte    "CLOSE FEED",0Ah,0
    msgmult     Byte    "MULTIPLE FEED",0Ah,0
    msgskew     Byte    "EXCESSIVE SKEW",0Ah,0
    msgfeed     Byte    "DOCUMENT MISFEED",0Ah,0
    msgjam      Byte    "DOCUMENT JAM",0Ah,0
    msgerror    Byte    "UNSPECIFIED ERROR",0Ah,0dsb          DWORD   ?.code
    main    PROCINVOKE      printf, ADDR msg1fmt, ADDR msg1INVOKE       scanf, ADDR in1fmt, ADDR dsbINVOKE      printf, ADDR msg2fmt, ADDR msg2, dsb
    while01:    cmp dsb, 0ffh           ; .while dsb<=0ffhjg    endwhile01   test dsb, 00000001b
    if01:       .if !ZERO?INVOKE    printf, ADDR msg1fmt, ADDR msgshort
    endif01:    .endiftest dsb, 00000010b
    if02:       .if !ZERO?INVOKE    printf, ADDR msg1fmt, ADDR msglong
    endif02:    .endif    test dsb, 00000100b
    if03:       .if !ZERO?INVOKE    printf, ADDR msg1fmt, ADDR msgclose
    endif03:    .endif     test dsb, 00001000b
    if04:       .if !ZERO?INVOKE    printf, ADDR msg1fmt, ADDR msgmult
    endif04:    .endif    test dsb, 00010000b
    if05:       .if !ZERO?INVOKE    printf, ADDR msg1fmt, ADDR msgskew
    endif05:    .endif    test dsb, 00100000b
    if06:       .if !ZERO?INVOKE    printf, ADDR msg1fmt, ADDR msgfeed
    endif06:    .endif   test dsb, 01000000b
    if07:       .if !ZERO?INVOKE    printf, ADDR msg1fmt, ADDR msgjam
    endif07:    .endif test dsb, 10000000b
    if08:       .if !ZERO?INVOKE    printf, ADDR msg1fmt, ADDR msgerror
    endif08:    .endif INVOKE   printf, ADDR msg1fmt, ADDR msg1INVOKE   scanf, ADDR in1fmt, ADDR dsbINVOKE  printf, ADDR msg2fmt, ADDR msg2, dsbendwhile01: nop         ;.endwret
    main    ENDP
    END     main
    
附:Intel x86汇编环境搭建与配置
  1. 打开VS2017, 选择VC++的“桌面安装向导”,创建项目

  2. 勾选“空项目”(有的VS版本还有安全周期检查,若有的话则把它也去掉),确定

  3. 右键项目 → \rightarrow →生成依赖项 → \rightarrow →生成自定义

  4. 勾选masm,确定

  5. 然后在源文件夹下创建如图所示的源文件,后缀名为.asm

    1. 右键项目 → \rightarrow →属性 → \rightarrow →弹出属性页,进行如下设置:



  6. 设置完成,写个示例代码编译调试

    .386
    .model flat, c
    .stack 100hincludelib msvcrt.lib   ;输入输出函数所在的库printf PROTO arg1:Ptr Byte, printlist:VARARG.data
    msg1fmt Byte "%s%d", 0
    msg1    Byte "Hello World! ",0Ah, 0
    num1    SDWORD ?.code
    main PROCmov num1, 7777INVOKE printf, ADDR msg1fmt, ADDR msg1, num1ret
    main ENDPEND main
    

    运行结果如下:

    设置完成!!!

《汇编语言基础教程》 学习实录相关推荐

  1. linux磁盘符变化autofs,Linux基础教程学习笔记之Autofs自动挂载

    Linux基础教程学习笔记之Autofs自动挂载 Autofs自动挂载: yum -y install autofs vim /etc/auto.master  在文件中添加下面行 /home/gue ...

  2. 网络存储 linux 访问,Linux基础教程学习笔记28——使用Samba访问网络存储

    Linux基础教程学习笔记28--使用Samba访问网络存储 SMB用于Windows和类Linux系统直接的文件共享 安装samba client包: [root@linuxidc~]# yum i ...

  3. 黑马程序员最新版JavaWeb基础教程-学习笔记

    da@黑马程序员最新版JavaWeb基础教程-学习笔记 day06-HTML&CSS HTML HTML(HyperTest Markup Language):超文本标记语言 是一门语言,所有 ...

  4. SQL基础教程学习第六站:数据更新

    仅用于记录学习,欢迎批评指正,共同交流,共同进步,大神勿喷 系列文章 SQL基础教程学习第一站:PostgreSQL下载安装以及如何创建并登录数据库: SQL基础教程学习第二站:数据库基本知识: SQ ...

  5. 批量加水印加logo#ps入门基础教程学习ps视频教程

    批量加水印加logo#ps入门基础教程学习ps视频教程修图后期

  6. Python基础教程学习笔记:第一章 基础知识

    Python基础教程 第二版 学习笔记 1.python的每一个语句的后面可以添加分号也可以不添加分号:在一行有多条语句的时候,必须使用分号加以区分 2.查看Python版本号,在Dos窗口中输入&q ...

  7. python基础教程-学习python有什么好的视频教程?

    干货来袭,以下均为python好的学习视频,我们先从python的入门教程开始分享起! python入门教程(600集)https://www.bilibili.com/video/BV1ex411x ...

  8. 【莫烦Python】Python 基础教程——学习笔记

    文章目录 本笔记基于p1-p29[莫烦Python]Python 基础教程 大家可以根据代码内容和注释进行学习. 安装 我的:python3.8+anaconda+VS code print() pr ...

  9. three.js基础教程学习之camera的理解

    最近学习了three.js基础教程,由于WebGL中文网中对camera的解说不够详细,自己又找了几篇博文看,以下是我对camera的理解,有错误的地方希望得到大佬们的指出,同时也希望能帮到像我一样的 ...

最新文章

  1. GitLab 简易指引(二):GitLab Runner 安装与配置
  2. 理解java并发工具Phaser
  3. IAR J-Link下载程序出现错误提示:Failed to get CPU status after 4 retries Retry?
  4. kafka的消费隔离级别(持续更新中)
  5. linux “命令行自动补全”功能用命令
  6. 一个简单的Python爬虫
  7. C++网络编程实例(socket)
  8. 乾颐堂安德最新HCNP真题讲解含2017年最新变题后题库,75到90题
  9. weka下载后没有安装java_Weka程序原版安装文件[下载指引]
  10. HITB_Binary_100_writeup
  11. webrtc音频QOS方法四(音频接收端NACK流程实现)
  12. 使用EXCEL计算并绘制MACD指标
  13. 计算机主机的声音线是哪个好,电脑显示器连接线哪种接口好|VGA、HDMI视频接口选哪个好...
  14. 做自媒体,不用露脸拍视频,方法都在这篇文章
  15. python报错系列(9)--SyntaxError: Missing parentheses in call to ‘print‘. Did you mean print()
  16. GPS授时服务器(NTP授时)为银行系统提供时间服务
  17. Codeforces-715A-Plus and Square Root(找规律)
  18. 时事评论---宣誓不欠薪,好一场秀
  19. 微信小程序支付开发具体步骤
  20. 什么是高防CDN?高防CDN的用处有哪些?

热门文章

  1. uniapp 实现代码高亮
  2. 黄金时代 —— 深度学习 (目标检测)
  3. #金专奖获奖方案展播# | 移动端云机魔测平台
  4. HOWTO:通过 VBA 自定义 Office 助手
  5. 数据表(中间表)的设计:多对多关系
  6. 试题 算法训练 黑心药商 ALGO-1002
  7. 测试沟通中的必备专业名称
  8. LeetCode刻意练习22--二叉树的中序遍历
  9. 不太常用,但万一用到一定要会的vue打印功能
  10. 云存储及分布式创新应用笔记一