一、1.汇编指令、寄存器和寻址方式

立即数:可以立即在一条机器指令后找到具体数值的数,如内存中00位写着加指令,01位写着1100_1111,意思就是将1100_1111(十进制207)加到某处,反之可以表示数据的地址。

请添加图片描述

低端字节序:16位寄存器数据存入内存(内存单位为8位),寄存器低位存入内存低位(如00)高位存入内存高位(如01),内存到寄存器同样

请添加图片描述

程序的重定位难题:当内存中的数据因为某种情况需要移动时,只是简单地将内存地址(绝对内存地址)写到指令中就不行了,会导致重定位错误。

为了解决重定位问题,使用[段地址:偏移地址]来描述数据的地址

请添加图片描述

此时如果发生内存数据的移动(以段为单位进行移动),只需要改变段地址的内容,就还可以定位到数据(有点像C中的宏定义)

8086的分段机制:有两个寄存器CS和DS,分别存放代码段和数据段的具体段地址,但是内存地址提供了20根地址线,而两个段寄存器只有16位(如CS可表示0XAB12,而内存地址却为0XAB120)。将内存地址右移4位(吞掉末位的那个0)来存入段寄存器,取出时再左移4位(补上末位0),这样段地址就存入了寄存器,再通过指针指令寄存器IP表示偏移地址,[CS:IP]表示出代码地址

因此对于一个数据,可以由多个段+偏移来表示

请添加图片描述

Notepad++集成nasm编译:运行 -> 运行 -> 输入cmd /k pushd “KaTeX parse error: Expected 'EOF', got '&' at position 22: …NT_DIRECTORY)" &̲ E:\NASM\nasm.e…(FULL_CURRENT_PATH)” -o “$(NAME_PART).bin” & PAUSE & EXIT 保存 -> 设置快捷键

8086内存地址分配:

请添加图片描述

请添加图片描述

8086加电复位时处理器向内存发出的指令是FFFF0,距离内存结束只有16字节,这16字节存放有跳转指令,在跳转的目的地,一般会把磁盘的0头0柱1扇区(主引导扇区)的数据加载到那里,以此执行对应的程序。

填充主引导扇区的512字节来作为初始程序,若不满足512字节,则不识别,同时,必须以0XAA55结尾

mov ax, 0x30
mov dx, 0xc0
add ax, dx

times 510-($-$$) db 0 ;$为当前地址,$$为汇编文件开始的段地址,($-$$)表示本行的段内偏移量,填充0
dw 0xaa55

标号:汇编代码由三个可选的部分组成 标号-指令-注释,标号表示离他最近的下一指令的地址

上段代码等效于

start:
	mov ax, 0x30
    mov dx, 0xc0
    add ax, dx
current:
    times 510-(current-start) db 0
    dw 0xaa55

逻辑块地址:物理上磁盘分为柱面-磁头-扇区(CHS),但是表示困难,所以采用逻辑块地址(LBA)的方式表示,即对每个扇区编号

请添加图片描述

请添加图片描述

屏幕显示文字:显存中存放屏幕显示的相关内容数据,显存映射到内存的地址中

请添加图片描述

请添加图片描述

请添加图片描述

mov ax, 0xb800
mov ds, ax

mov byte [0x00], 'l' ;向显存映射到内存的地方写数据,默认在ds表示的段中写
mov byte [0x01], 0x02;0x01只是偏移地址,无法确定操作的位数,0x04同样可以理解为0x0004,无法确定位数,所以需要加byte指定以字节进行mov
;如果操作数之一确定了操作的位数(如固定位数的寄存器)则不需要指定位数
mov byte [0x02], 't'
mov byte [0x03], 0x02

mov byte [0x04], 'y'
mov byte [0x05], 0x02
;mov指令不允许在内存单元之间直接传输数据

times 510-($-$$) db 0
dw 0xaa55

使用nasm xxx.asm -l xxx.lst生成汇编代码的列表文件,方便观察汇编后数据和代码的对应关系

请添加图片描述

汇编地址:每条指令在程序汇编阶段确定的地址

段间直接绝对跳转指令:jmp 段地址:偏移地址如设置jmp 0x0000:0x7c00则将跳转至主引导扇区开头重新执行

请添加图片描述

mov ax, 0xb800
mov ds, ax
...
jmp 0x0000:0x7c00+$ ;段间直接绝对跳转指令,使处理器卡在本行程序 

times 510-($-$$) db 0
dw 0xaa55

绝对间接近跳转:使用寄存器对绝对偏移地址进行间接存储,只能在CS表示的当前段内跳转

mov ax, 0xb800
mov ds, ax
...
mov bx, 0x7c00+again
again:
	jmp bx 

times 510-($-$$) db 0
dw 0xaa55

使用相对偏移量的短/近跳转:使用标号

mov ax, 0xb800
mov ds, ax
...
again:
	jmp again ;近跳转用jmp short 8位跳转相对偏移量,远跳转用jmp near 16位跳转相对偏移量,不加自动识别

times 510-($-$$) db 0
dw 0xaa55

无符号除法:

  • 操作数8位(除数)-被除数16位:AX ÷ 操作数 = AL···AH
  • 操作数16位(除数)-被除数32位:DX_AX ÷ 操作数 = AX···DX
  • 操作数32位(除数)-被除数64位:EDX_EAX ÷ 操作数 = EAX···EDX(8086不支持,80386开始支持)
  • 操作数64位(除数)-被除数128位:RDX_RAX ÷ 操作数 = RAX···RDX(8086和32位处理器不支持,6位处理器支持)
mov ax, 0xffff
mov bx, 10

mov cx, 0
mov ds, cx

;除5次bx,从而取出单个数字,存入内存
xor dx, dx
div bx
add dl, 0x30
mov [0x7c00+buffer], dl

xor dx, dx
div bx
add dx, 0x30
mov [0x7c00+buffer+1], dl

xor dx, dx
div bx
add dx, 0x30
mov [0x7c00+buffer+2], dl

xor dx, dx
div bx
add dx, 0x30
mov [0x7c00+buffer+3], dl

xor dx, dx
div bx
add dx, 0x30

;ds标识结果各数字段(0x0000)es标识显存段(0xb800)
mov cx, 0xb800
mov es, cx

mov [es:0x00], dl
mov byte [es:0x01], 0x02

mov dl, [0x7c00+buffer+3]
mov [es:0x02], dl
mov byte [es:0x03], 0x02

mov dl, [0x7c00+buffer+2]
mov [es:0x04], dl
mov byte [es:0x05], 0x02

mov dl, [0x7c00+buffer+1]
mov [es:0x06], dl
mov byte [es:0x07], 0x02

mov dl, [0x7c00+buffer]
mov [es:0x08], dl
mov byte [es:0x09], 0x02

buffer:
	db 0, 0, 0, 0
	
jmp 0x0000:0x7c00+$

times 510-($-$$) db 0
dw 0xaa55

串传送指令:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-i3wILzQV-1691295231112)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20230729144708214.png)]

jmp start
text:
	db 'l', 0x02, 't', 0x02, 'y', 0x02

start:
	mov ax, 0x7c0 ;本段物理地址为0000:7c00,即7c00,当ds取0000时必须标号前加7c00,当ds取07c0时0偏即7c00,汇编地址即物理地址,标号前不用加7c00
	mov ds, ax
	
	mov ax, 0xb800
	mov es, ax
	
	cld ;设定传送方向为低地址向高地址(标志寄存器清零),反之为std(标志寄存器置位)
	mov si, text ;原始位置偏移地址
	mov di, 0 ;目标位置偏移地址
	mov cx, (start-text)/2 ;控制重复执行movsw几次
	rep movsw
jmp $
times 510-($-$$) db 0
dw 0xaa55

循环

number:
	db 0, 0, 0, 0, 0
start:
    mov ax, number
    mov bx, ax
    mov si, 10 ;除数
    mov cx, 5 ;控制循环次数
lab:
	xor dx, dx
	div si
	mov [bx], dl ;bx又叫基址寄存器,可用来寻址
	inc bx ;自增,dec自减
	loop lab
jmp $
times 510-($-$$) db 0
dw 0xaa55

请添加图片描述

求补码:neg 寄存器或内存地址

请添加图片描述

有符号除法指令:idiv 除数,除适用有符号数外,同无符号除法

余数的符号始终与被除数相同

标志寄存器:

请添加图片描述

请添加图片描述

请添加图片描述

请添加图片描述

请添加图片描述

请添加图片描述

请添加图片描述

使用栈进行数位分解并显示

xor cx, cx
mov ss, cx ;栈的段地址0x0000
mov sp, cx ;栈顶初始地址0x0000,每次入栈sp减2(16位,2字节),高地址向低地址移动

mov bx, 10
xor cx, cx
; 分解数位
lab:
	inc cx ;记录入栈次数
	xor dx, dx
	div bx
	add dl, 0x30
	push dx ;入栈,16位处理器出入栈必须16位
	cmp ax, 0 ;判断ax是否被除完
	jne lab
	
show:
	pop dx
	mov [es:di], dl
	inc di
	mov byte [es:di], 0x02
	inc di
	loop show
	

就像[BX]直接表示DS段内存相应偏移量下内容一样,使用[BP]直接表示SS段内存的值

mov bp, sp
mov dx, [bp+2]

请添加图片描述

几种寻址方式:

  • mov ax, cx两个操作数都是寄存器寻址
  • add bx, 0xf000右操作数是立即数寻址,标号会直接编译成地址,所以也是立即数寻址
  • 内存寻址
    • mov ax, [es:0x50c0]右操作数是直接(内存)寻址
    • inc word [ss:bx+2]使用基址寻址
    • mov [si+lab], dx用SI或DI进行内存寻址(DS段),变址寻址
    • mov ax, [bx+si+0x03]基址变址寻址
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值