week 3 - Assembly Language

Important Instructions and Syntax

此内容是以MASM编写的,你将使用Visual C/C++内联汇编来编程,因此数据元素的声明有所不同,但概念和指令集(instruction sets)相同。

一、General-Purpose Registers

寄存器是CPU内的命名存储单元,设计上优化了速度。

Registers are named storage locations inside the CPU, optimized for speed.

解释:一般用途寄存器是CPU内部用于快速存取数据的特殊存储位置,主要用于处理和操作数据。

1. Accessing Parts of Registers(访问寄存器的部分)

这张图展示了如何访问32位寄存器的不同部分。一个32位寄存器(如EAX)可以拆分为16位的AX和8位的AH(高8位)与AL(低8位)。这意味着可以通过使用不同的位宽名称(8位、16位或32位)来访问寄存器的不同部分,这种方式适用于EAX、EBX、ECX和EDX寄存器。

这种分块设计可以在不更改整个寄存器内容的情况下,只修改特定部分,提高了操作的灵活性

2. Index and Base Registers(索引和基址寄存器)

索引和基址寄存器(如ESI、EDI、EBP和ESP)。这些寄存器既有32位的名称(如ESI)也有16位的名称(如SI),但它们不具备像通用寄存器(EAX等)那样的8位部分。这些寄存器常用于存储地址、指向数据或管理堆栈操作。

3. Some Specialized Register Uses

EAX通常用作累加器,ECX用作循环计数器,ESP是堆栈指针,EBP是扩展帧指针,ESI和EDI则用于索引操作。段寄存器(如CS、DS、SS等)则用于划分不同的内存段,分别对应代码段、数据段和堆栈段等。

EIP(指令指针)和EFLAGS寄存器的功能。EIP用于存储下一条指令的位置,控制程序的执行流。EFLAGS则包含多个标志位,用于反映程序运行时的状态(如零标志、进位标志等),每个标志都是一个二进制位,用来控制或指示特定的状态。

二、Instructions

汇编器将指令编译成机器码,运行时由CPU执行。

Assembled into machine code by the assembler and executed by the CPU at runtime.

此处使用的是Intel IA-32指令集。指令由四个部分组成:

Label(标签):用于标记代码位置--optional

Mnemonic(助记符)指令名称,用于指定操作类型(如MOV、ADD)-- required

Operand(操作数):指令的具体操作对象,取决于指令类型。

Comment(注释):--optional

1. Labels(place markers)

标签用作位置标记,标记代码或数据的地址(偏移量offset)。标签需遵循标识符(identifer)规则,分为数据标签和代码标签:

Data label:必须唯一,例如myArray(不带冒号colon)。

Code label:通常作为跳转指令的目标,例如L1:(带冒号)。

                          target of jump and loop instructions

(标签在代码中用于标记特定位置,便于跳转和引用。数据标签标记变量位置,代码标签标记指令位置)

2. Mnemonics(memory aid) and Operands

助记符是指令的缩写,用于帮助记忆指令的功能,如MOV、ADD、SUB等。

操作数则是指令的操作对象,可以是常量、常量表达式、寄存器或内存地址(数据标签)。

Constants and constant expressions are often called immediate values

3. Comments

single -line comments:以分号(semicolon)开头。

Multi-line comments:COMMENT指令可以用于多行注释,格式是指定一个特定字符(a programmer-chosen character)作为开始和结束标记。如 ;、# 

COMMENT *
……
*

4. Instruction Format Examples

不同操作数数量的指令格式示例:

(1) No operands(无操作数)

stc:设置进位标志(Carry Flag)。这是一个无操作数的指令,它只影响CPU标志寄存器的状态,而不需要其他的操作数。

(2) One operand(单操作数)

inc eax:对寄存器 eax 的值加 1。inc 是递增指令,用于将指定操作数的值增加 1。

inc myByte:对内存位置 myByte 的值加 1。inc 可以作用于内存位置,将该内存位置的值增加 1。

(3) Two operands(双操作数)

add ebx, ecx:将寄存器 ecx 的值加到寄存器 ebx 上,结果存储在 ebx 中。add 指令用于加法操作,通常用于两个寄存器之间的数据运算。

sub myByte, 25:将常量 25 从内存位置 myByte 的值中减去,结果存储在 myByte 中。sub 指令用于减法操作,可以对内存数据进行减法。

add eax, 36 * 25:将表达式 36 * 25 的结果加到寄存器 eax 上。add 指令可以接受常量表达式作为操作数,这里 36 * 25 作为一个立即数添加到 eax 中。

三、MOV Instruction

用于将数据从源位置(source)复制到目标位置(destination)(传输数据)

MOV destination, source.

• 只允许一个内存操作数(memory operand),CS、EIP、IP不能作为目标(destination),不能直接向段寄存器(如DS、CS、SS等)赋值立即数。

No immediate to segment moves.

立即数(Immediate Value):直接的数值,立即数只能作为源操作数,不能作为目标操作数。因为立即数是常量,不能被修改

寄存器(Register):用于存储临时数据。在x86架构中,寄存器的位宽类型必须和操作数位宽一致。

内存地址(Memory Address):指向一个内存位置的变量或常量,在代码中常通过变量名表示。内存到内存的数据传递不被允许,至少一个操作数必须是寄存器。

需要通过寄存器中转

mov al, bVal
mov bVal2, al

指令指针寄存器(如EIP):存储下一条将要执行指令的地址,它是只读的,不能直接通过mov指令修改。只能通过跳转指令(如JMP、CALL)间接改变

.data
count BYTE 100    ; 定义一个8位的变量count,值为100
wVal WORD 2       ; 定义一个16位的变量wVal,值为2
.code
mov bl, count     ; 将8位变量count的值移动到8位寄存器bl中
mov ax, wVal      ; 将16位变量wVal的值移动到16位寄存器ax中
mov count, al     ; 将8位寄存器al的值移动到8位变量count中 

.data:是一个伪指令(directive),用于定义程序中的静态数据(变量和常量),数据段中的变量可以初始化也可以不初始化。

BYTE:表示8位(1字节)数据,例如 BYTE 100 表示一个8位的变量,值为100。

WORD:表示16位(2字节)数据,例如 WORD 2 表示一个16位的变量,值为2。

DWORD:表示32位(4字节)数据,例如 DWORD 5 表示一个32位的变量,值为5。

• .code:是一个伪指令(directive),用于定义程序的执行代码,即指令序列。程序在执行时会从代码段开始逐条指令执行。

错误代码部分

mov al, wVal        ;al是8位寄存器,而wVal是16位变量,位宽不匹配,因此报错。

mov ax, count        ;ax是16位寄存器,而count是8位变量,位宽不匹配,因此报错。

 .data
bVal BYTE 100       ; 定义一个8位的变量bVal,值为100
bVal2 BYTE ?        ; 定义一个8位的变量bVal2,未初始化
wVal WORD 2         ; 定义一个16位的变量wVal,值为2
dVal DWORD 5        ; 定义一个32位的变量dVal,值为5
.code
mov ds, 45          ; 错误:不允许将立即数45直接移动到段寄存器ds
mov esi, wVal       ; 错误:esi是32位寄存器,而wVal是16位变量,位宽不匹配
mov eip, dVal       ; 错误:eip是指令指针寄存器,只读,不能作为目标
mov 25, bVal        ; 错误:立即数25不能作为目标操作数
mov bVal2, bVal     ; 错误:内存到内存的移动不被允许

Zero Extension and Sign Extension

Zero Extension:movzx ax, bl 用零扩展将小值复制到较大目标寄存器,目标(destination)必须是寄存器。

mov bl, 10001111b    ; 将二进制数10001111加载到8位寄存器BL中
movzx ax, bl         ; 使用MOVZX将BL扩展到16位寄存器AX,结果为00000000 10001111

Sign Extension:movsx ax, bl 用符号(sign bit)扩展将小值复制到较大目标寄存器。MOVSX指令的目标必须是寄存器,不能是内存位置。

mov bl, 10001111b    ; 将二进制数10001111加载到8位寄存器BL中
movsx ax, bl         ; 使用MOVSX将BL扩展到16位寄存器AX,结果为11111111 10001111

由于bl的最高位是1,表示一个负数,因此ax的高位也被填充为1,保持了符号的一致性。

二、XCHG Instruction

XCHG(Exchange)指令用于交换两个操作数的值。此指令有以下限制:

• 至少有一个操作数(operands)必须是寄存器。

• 不允许立即数(immediate operands)作为操作数。

• 不能直接交换两个内存位置,至少需要一个寄存器参与。

.data
var1 WORD 1000h      ; 定义一个16位变量var1,值为1000h
var2 WORD 2000h      ; 定义一个16位变量var2,值为2000h
.code
xchg ax, bx          ; 交换两个16位寄存器AX和BX的值
xchg ah, al          ; 交换两个8位寄存器AH和AL的值
xchg var1, bx        ; 交换内存变量var1和寄存器BX的值
xchg eax, ebx        ; 交换两个32位寄存器EAX和EBX的值

xchg var1, var2      ; 错误:两个操作数都是内存位置(two memory operands)

三、INC and DEC Instructions

用于将目标操作数(destination operand)加1或减(subtract)1,操作数可以是寄存器或内存。

•INC destination 等同于 destination = destination + 1

• DEC destination 等同于 destination = destination - 1

INC and DEC Examples

.data
myWord WORD 1000h           ; 定义一个16位变量myWord,初始值为1000h
myDword DWORD 10000000h     ; 定义一个32位变量myDword,初始值为10000000h
.code
inc myWord                  ; myWord的值增加1,变为1001h
dec myWord                  ; myWord的值减少1,恢复为1000h
inc myDword                 ; myDword的值增加1,变为10000001h

mov ax, 0FFh                ; 将0FFh加载到AX,AX = 00FFh
inc ax                      ; AX递增1,导致进位,结果为0100h
mov ax, 0FFh                ; 重新将00FFh加载到AX
inc al                      ; AL递增1(FFh + 1),结果为00h,AX变为0000h

AX 包含 AHAL,但 AHAL 是独立的 8 位寄存器,分别表示 AX 的高 8 位和低 8 位

result:

• AX = 0000h

• AH = 00h

• AL = 00h

• inc al 指令只对 AX 的低8位 AL 进行递增操作。

• 当前 AL = FFh(即255)。inc al 将 FFh 加1,因为 AL 是8位寄存器,加1后会产生溢出,使 AL 回到 00h。

• 由于 AL 是 AX 的一部分,当 AL 变为 00h 时,整个 AX 的值也会随之改变。

.data
myByte BYTE 0FFh, 0         ; 定义一个8位变量myByte,第一个值为0FFh,第二个值为0
.code
mov al, myByte              ; 将myByte的第一个字节0FFh加载到AL中

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值