汇编程序语言设计 MOOC 郑州大学 第一周


学习记录和个人理解,非笔记,有误区,慎看!~

老狗转行系列之汇编:
本职烧锅炉,现转AI系列,基础薄弱,目前正在学习基础,有兴趣的一起来~

第一周

1.硬件组成

1.1 寄存器

在这里插入图片描述

重点:硬件分为三个部分:寄存器,输入输出地址,储存器地址
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
这节课重要的知识点IA32有8个重要寄存器,重点记忆下面一图。
在这里插入图片描述
32位寄存器之间到底有什么区别,是不是可以混用等???EAX、EBX、ECX、EDX、ESI、EDI、ESP、EBP 寄存器详解每个汉字我都懂,连在一起蒙圈系列
推荐王爽《汇编语言》
(转)
在用途方面,他们有各自默认的用途:
Eax用来保存所有API函数的返回值。
寄存器AX和AL通常称为累加器(Accumulator),用累加器进行的操作可能需要更少时间。累加器可用于乘、除、输入/输出等操作,它们的使用频率很高;
寄存器BX称为基地址寄存器(Base Register)。它可作为存储器指针来使用;
寄存器CX称为计数寄存器(Count Register)。在循环和字符串操作时,要用它来控制循环次数;在位操作中,当移多位时,要用CL来指明移位的位数;
寄存器DX称为数据寄存器(Data Register)。在进行乘、除运算时,它可作为默认的操作数参与运算,也可用于存放I/O的端口地址。

由于存储的数据大小关系,AX、BX、CX和DX不能作为基址和变址寄存器来存放存储单元的地址, 32位寄存器EAX、EBX、ECX和EDX不仅可传送数据、暂存数据保存算术逻辑运算结果,而且也可作为指针寄存器,所以,这些32位寄存器更具有通用性。(什么是基址,什么是变址以后会说到)

1.2 处理器专用寄存器

在这里插入图片描述

专用寄存器有三类:
第一类 标志
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
改变EIP是可以改变程序的顺序
存储空间是可以分段管理的
段寄存器
段
代码段
在这里插入图片描述
在这里插入图片描述

1.3 存储器

在这里插入图片描述
计算机被分为三个部分,CPU 存储器 IO。存储器对应存储器地址
在这里插入图片描述
在这里插入图片描述
8位形成字节,16位形成字,32位形成双字,一个存储单位存放的是一个字节,称字节编址。32位可以表征2的32次的名字。32位处理器最多一次处理32位,EAX是32位的
在这里插入图片描述
4个二进制,相当于1个16位,32位二进制相当于8个16进制位。H表示16位进制。
在这里插入图片描述
MMU存储管理单元。如果程序直接寻找存储器地址是会给存储管理带来麻烦,所以有MMU。
在这里插入图片描述
后续学习最多的是平展存储模型。
在这里插入图片描述
在这里插入图片描述
物理地址与逻辑地址
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
32位存储空间的划分,可以分为以上部分。

2.程序格式

2.1 处理器指令格式

小结:
指令由操作码和操作数(地址码)组成,左右注意。
处理器指令
在这里插入图片描述
这条指令有点像高级语言中的赋值
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
机器代码也叫指令格式,按照习惯使用16位表示
在这里插入图片描述
里面的8B是操作码,操作数部分(Mod R/M)是第二列,SIB也是一种寻址的方式,后面的四个字节都是位移量(80 00 00 00)。上面的格式可能很难理解,但是我们要知道我们高级语言都需要转换成这种机器代码。然后机器代码也不同,同一指令不容数据内容也可能不同。

2.2 语句格式

在这里插入图片描述
在这里插入图片描述
标号与名字都是用户自己定义的。
在这里插入图片描述
在这里插入图片描述
定义一个字符
在这里插入图片描述
在这里插入图片描述
eax也是寄存器,offset msg是操作数
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
执行性语句,有点像高级语言中的操作。
说明性语句,有点像高级语言的赋值定义等

2.3 源程序框架

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
stdcall 是标准调用规范
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
PS:“END”伪指令仅说明汇编到此结束,并不具备返回操作系统的功能。

2.3 信息显示程序

在这里插入图片描述
第一个汇编语言程序
在这里插入图片描述
13,10对应是\n,在底层内部都是有0 结尾的,字符串结尾字符。这里面Dismsg 相当于Printf()。通过OFFset指出偏移地址。EAX是寄存器,他是进行显示的一个入口参数存放的地方。
在这里插入图片描述
在这里插入图片描述
程序在IO32.lib 其说明是IO32.inc
注意子程序调用规范
在这里插入图片描述
库是前人设计的规范
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
问题:汇编中定义字符的时候有段基地址什么?

3.开发过程

3.1 MASM开发软件

最主要的是什么系统平台:WINDOWS
在这里插入图片描述
在这里插入图片描述
汇编程序是将我们源代码转成机器代码的程序。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

3.2 操作系统平台

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
常称为DOS窗口,但是实际上不是
在这里插入图片描述
这两者本质有不同
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

3.3 源程序开发

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
汇编只是生成一个目标模板文件,然后需要连接称为可执行文件。
在这里插入图片描述
不能双击是因为我们生成的控制台,双击并不能看到信息
在这里插入图片描述
调试程序:
在这里插入图片描述
在这里插入图片描述
所谓快速开发,MAKE32就是将步骤汇合在一起
在这里插入图片描述

4.程序

1.标准的Hello world

    include io32.inc
    .data
        ;数据定义
msg     byte 'Hello ,World!',13,10,0
;msgzn     byte '你好,瓜娃子!',13,10,0
    .code
start:
        ;主程序
    mov eax,offset msg      ;显示  这边为什么eax 为什么使用offset 
    ;mov ebx,offset msg
    ;mov ecx,offset msg
    ;mov eax,msg
    call dispmsg
    exit 0
        ;子程序
    end start

在这里插入图片描述
2.测试中文可以否

    include io32.inc
    .data
        ;数据定义
;msg     byte 'Hello ,World!',13,10,0
msg     byte '你好,瓜娃子!',13,10,0
    .code
start:
        ;主程序
    mov eax,offset msg      ;显示  这边为什么eax 为什么使用offset 
    ;mov ebx,offset msg
    ;mov ecx,offset msg
    ;mov eax,msg
    call dispmsg
    exit 0
        ;子程序
    end start

在这里插入图片描述
3.测试不用msg1 其他字符

    include io32.inc
    .data
        ;数据定义
xjbx     byte 'Hello ,World!',13,10,0
;msg     byte '你好,瓜娃子!',13,10,0
    .code
start:
        ;主程序
    mov eax,offset xjbx      ;显示  这边为什么eax 为什么使用offset 
    ;mov ebx,offset msg
    ;mov ecx,offset msg
    ;mov eax,msg
    call dispmsg
    exit 0
        ;子程序
    end start

在这里插入图片描述
4.使用其他寄存器

    include io32.inc
    .data
        ;数据定义
msg     byte 'Hello ,World!',13,10,0
;msg     byte '你好,瓜娃子!',13,10,0
    .code
start:
        ;主程序
    ;mov eax,offset msg      ;显示  这边为什么eax 为什么使用offset 
    mov ebx,offset msg
    ;mov ecx,offset msg
    ;mov eax,msg
    call dispmsg
    exit 0
        ;子程序
    end start

在这里插入图片描述
这里看样子不行啊

    include io32.inc
    .data
        ;数据定义
msg     byte 'Hello ,World!',13,10,0
msg2     byte '你好,瓜娃子!',13,10,0
    .code
start:
        ;主程序
    mov eax,offset msg      ;显示  这边为什么eax 为什么使用offset 
    mov ebx,offset msg2
    ;mov ecx,offset msg
    ;mov eax,msg
    call dispmsg
    call dispmsg
    exit 0
        ;子程序
    end start

在这里插入图片描述
5.为什么使用offset 去掉行不行

    include io32.inc
    .data
        ;数据定义
msg     byte 'Hello ,World!',13,10,0
;msg2     byte '你好,瓜娃子!',13,10,0
    .code
start:
        ;主程序
    ;mov eax,offset msg      ;显示  这边为什么eax 为什么使用offset 
    ;mov ebx,offset msg2
    mov eax,msg
    call dispmsg
    ;call dispmsg
    exit 0
        ;子程序
    end start

在这里插入图片描述
看样子不太好使,eax为通用寄存器,主要是存放地址,直接将数据复制进去看来不太行。关于move ax @data
6.案例代码:推测应该是使用了子程序

;eg0201a.asm
	include io32.inc
WriteString	macro msg
	mov eax,offset msg		;显示
	call dispmsg
	endm
	.data
msg    byte 'Hello, Assembly !',13,10,0	;字符串
	.code
start:

	WriteString msg
	exit 0
	end start

以下为推测解释:
WriteString macro msg 到endm 为子程序
在start后面使用了该程序,但是并没有使用call命令并不是很能理解?
从反复使用msg却不报错的情况来看,应该不同段里面的指令是局部的,不是全局的。

自己写一遍

; eg0000.asm in Windows Console
	include io32.inc
Printf      macro msg
    mov eax,offset msg
    call dispmsg
    endm
	.data
		; 数据定义
msg     byte 'Hello,This is a small step',13,10,0
	.code
start:
		; 主程序
	Printf msg
	exit 0
		; 子程序
	end start
	
	;报错历史
	;前面定义Printf 后面使用printf 是会报错的,这里区分大小写
	;move eax,msg 如果不写‘,’,写出move eax msg 报错errorA2008
	;将mov 写成move

这里一定要注意是 move eax,offset msg 而不是move eax ,msg不然也报错
好吧,注意是mov eax。。。不是move eax
在这里插入图片描述
事实证明自己写报错无数。。。。。
在这里插入图片描述

7.案例代码:DOS代码

; eg0201d.asm in MS-DOS
	include io16.inc
	.data
msg    byte '你好,汇编语言!',13,10,0	;字符串
	.code
start:
	mov ax,@data
	mov ds,ax
	mov eax,offset msg		;显示
	call dispmsg

	exit 0
	end start

在这里插入图片描述
用window控制台打开报错,果然呀~
8、/20181128更新:建议最好要本书啊,王爽的就行,该MOOC课程排课顺序有点不太建立体系,需要书建立体系。

        include io32.inc
        .data
count   dword 12345678h,9abcdef0h,0,0,3721h
msg1    byte 'hello',13,10,0
        .code
start :
        ;mov eax,33221100h
        ;mov ebx,eax
        mov ebx,offset msg1
        mov eax,ebx
        ;mov 
        call dispmsg
        
        exit 0
        end start

首先dispmsg应该是默认定义在了eax上,然后通过eax指向显示内容。eax为32位寄存器,保存的内容就是二进制32位的整数。所以直接将字符赋值给eax是不好使得。
之前定义msg byte 。。。然后mov eax,msg 相当于将msg第一个数据赋值给eax,而‘hello’不是32位。mov al,msg是可以的。

        include io32.inc
        .data
count   dword 12345678h,9abcdef0h,0,0,3721h
msg1    byte 'hello world',13,10,0
        .code
start :
        mov eax,0h
        ;mov ebx,eax
        
        mov al,msg1
        ;mov eax,ebx
        ;mov 
        call disprd
        
        exit 0
        end start

在这里插入图片描述
查了一下,'h’对应的acsii码为68h,al为8位寄存器,也就小段更改数据。

  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值