第四章 数据传送,寻址和算术运算

4.1 数据传送指令

4.1.2 操作数类型

操作数有 3 种基本类型:

    1. 立即数——用数字文本表达式
    2. 寄存器操作数——使用 CPU 内已命名的寄存器
    3. 内存操作数——引用内存位置
操作数说明
reg8 8 位通用寄存器:AH、AL、BH、BL、CH、CL、DH、DL
reg16 16 位通用寄存器:AX、BX、CX、DX、SI、DI、SP、BP
reg32 32 位通用寄存器:EAX、EEX、ECX、EDX、ESI、EDI、ESP、EBP
reg 通用寄存器
sreg 16 位段寄存器:CS、DS、SS、ES、FS、GS
imm 8 位、16 位或 32 位立即数
imm8 8 位立即数,字节型数值
imm16 16 位立即数,字类型数值
imm32 32 位立即数,双字型数值
reg/mem8 8 位操作数,可以是 8 位通用寄存器或内存字节
reg/mem16 16 位立即数,可以是 16 位通用寄存器或内存字
reg/mem32 32 位立即数,可以是 32 位通用寄存器或内存双字
mem 8位、16 位或 32 位内存操作数

直接内存操作数:变量名引用的是数据段内的偏移量。

4.2 加法和减法

4.2.4 NEG指令

NEG:通过将数字转换为对应的补码而求得其相反数。

TITLE Add and Subtract

INCLUDE Irvine32.inc

;计算26+(-25)
.data
Val SDWORD 25

.code
main PROC
mov eax,Val
neg eax;-25
add eax,26

call DumpRegs

INVOKE ExitProcess,0
main ENDP
END main

4.3 和数据相关的操作符和伪指令

OFFSET 运算符返回数据标号的偏移量。这个偏移量按字节计算,表示的是该数据标号距离数据段起始地址的距离。

TITLE test

INCLUDE Irvine32.inc

.data
Val SDWORD 25
Val1 SDWORD 66

.code
main PROC
mov esi,OFFSET Val
mov edi,OFFSET Val1
mov eax,0
mov eax,[esi]

call DumpRegs

INVOKE ExitProcess,0
main ENDP
END main

ALIGN 伪指令将一个变量对齐到字节边界、字边界、双字边界或段落边界。

bVal BYTE ?           ;00404000h
ALIGN 2 
wVal WORD ?           ;00404002h
bVal2 BYTE ?          ;00404004h
ALIGN 4 
dVal DWORD ?          ;00404008h
dVal2 DWORD ?         ;0040400Ch

PTR 运算符可以用来重写一个已经被声明过的操作数的大小类型。

TITLE test

INCLUDE Irvine32.inc

.data
Val SDWORD 12345678h

.code
main PROC
mov eax,0
mov ax,WORD PTR Val;ax=5678h

call DumpRegs

INVOKE ExitProcess,0
main ENDP
END main

TYPE 运算符返回变量单个元素的大小,这个大小是以字节为单位计算的。比如,TYPE 为字节,返回值是 1;TYPE 为字,返回值是 2;TYPE 为双字,返回值是 4;TYPE 为四字,返回值是 8。

LENGTHOF 运算符计算数组中元素的个数,元素个数是由数组标号同一行出现的数值来定义的。

LABEL 伪指令可以插入一个标号,并定义它的大小属性,但是不为这个标号分配存储空间。

.data
val16 LABEL WORD
val32 DWORD 12345678h
.code
mov ax,val16          ; AX = 5678h
mov dx,[val16+2]      ; DX = 1234h

4.4 间接寻址

4.4.1间接操作数

保护模式

任何一个 32 位通用寄存器(EAX、EBX、ECX、EDX、ESI、EDI、EBP 和 ESP)加上括号就能构成一个间接操作数。

变址操作数

变址操作数是指,在寄存器上加上常数产生一个有效地址。每个 32 位通用寄存器都可以用作变址寄存器。MASM 可以用不同的符号来表示变址操作数(括号是表示符号的一部分):

使用 16 位寄存器

在实地址模式中,一般用 16 位寄存器作为变址操作数。在这种情况下,能被使用的寄存器只有 SI、DI、BX 和 BP:

变址操作数中的比例因子

在计算偏移量时,变址操作数必须考虑每个数组元素的大小。比如下例中的双字数组,下标(3 )要乘以 4(一个双字的大小)才能生成内容为 400h 的数组元素的偏移量

4.4.4 指针

TITLE test program

INCLUDE Irvine32.inc
;创建用户自定义类型
PBYTE TYPEDEF PTR BYTE
PWORD TYPEDEF PTR WORD
PDWORD TYPEDEF PTR DWORD

.data
Str1 BYTE 1,2,3
Str2 WORD 4,5,6
Str3 DWORD 7,8,9
;创建指针变量
ptr1 PBYTE Str1
ptr2 PWORD Str2
ptr3 PDWORD str3

.code
main PROC
mov esi,ptr1;将指针变量的值赋值
mov eax,0
mov al,[esi + TYPE Str1]

mov eax,0
mov esi,ptr2
mov ax,[esi + TYPE Str2]

mov eax,0
mov esi,ptr3
mov eax,[esi + TYPE Str3]

call DumpRegs

exit
main ENDP
END main

4.7 编程练习

1.

Title Test Project

INCLUDE Irvine32.inc

.code
main PROC
    mov eax,0

    ;mov不影响标志寄存器
    mov ax,0FFFFh
    call DumpRegs

    ;add影响标志寄存器,且进位了(ax无法容纳10000h)
    add ax,2
    call DumpRegs

    ;sub影响标志寄存器,但未产生进位1-1=0000h
    sub ax,1
    call DumpRegs
    exit
main ENDP
END main

2.

Title Test Project

INCLUDE Irvine32.inc

.code
main PROC
    mov eax,0

    mov ax,0FFFFh
    call DumpRegs

    inc ax
    call DumpRegs

    inc ax
    call DumpRegs

    dec ax
    call DumpRegs

    dec ax
    call DumpRegs
    exit
main ENDP
END main

3.

Title Test Project

INCLUDE Irvine32.inc

.code
main PROC
    mov eax,0

    ;变成-1,影响符号位
    add ax,-1
    call DumpRegs

    ;变成0,影响符号位
    add ax,1
    call DumpRegs
    
    exit
main ENDP
END main

4.

Title Test Project

INCLUDE Irvine32.inc

.code
main PROC
    mov eax,0

    ;变成-1,影响符号位
    add ax,-1
    call DumpRegs

    ;变成0,影响符号位
    add ax,1
    call DumpRegs
    
    exit
main ENDP
END main

5.

Title Test Project

INCLUDE Irvine32.inc

.data
Uarray WORD 1000h,2000h,3000h,4000h
Sarray SWORD -1,-2,-3,-4

.code
main PROC
    mov eax,0
    mov ebx,0
    mov ecx,0
    mov edx,0

    movzx eax, Uarray
    movzx ebx, Uarray+2
    movzx ecx, Uarray+4
    movzx edx, Uarray+6

    call DumpRegs
    
    mov eax,0
    mov ebx,0
    mov ecx,0
    mov edx,0

    movsx eax, Sarray
    movsx ebx, Sarray+2
    movsx ecx, Sarray+4
    movsx edx, Sarray+6

    call DumpRegs


    exit
main ENDP
END main

6.

TITLE TEST PROJECT

INCLUDE Irvine32.inc

.data
NUM1 DWORD 1
NUM2 DWORD 1

.code
main PROC
    mov eax,0
    mov ebx,0
    mov edx,0
    mov ecx,0

    add eax,NUM1
    add eax,NUM2
    mov edx,NUM2;将edx作为当前的最大值

    mov ecx,10
S:
    mov ebx,NUM1
    mov NUM1,edx;最大值更新之后,NUM1将变成原最大值
    add edx,ebx;最大值edx更新
    add eax,edx;和更新
    LOOP S

    call DumpRegs
    exit
main ENDP
END main

7.

TITLE TEST PROJECT

INCLUDE Irvine32.inc

.data
val1 SDWORD 8
val2 SDWORD -15
val3 SDWORD 20

.code
main PROC
    mov eax,val2;eax=FFFF FFF1H
    NEG eax;eax=0000 0000FH
    add eax,7;eax=0000 0016H
    sub eax,val3;eax=0000 0002H
    add eax,val1;eax=0000 000AH

    call DumpRegs
    exit
main ENDP
END main

8.

TITLE TEST PROJECT

INCLUDE Irvine32.inc

.data
source BYTE "This is the source string",0
target BYTE SIZEOF source DUP('#')

.code
main PROC
    mov eax,0
    mov esi,0
    mov edi,SIZEOF source - 1;不能包含0,大小-1
    dec edi;末尾元素坐标,[size - 1]
    mov ecx,SIZEOF source - 1;大小-1
S:
    mov al,source[esi]
    mov target[edi],al
    inc esi
    dec edi
    loop S

    mov esi,OFFSET target
    mov ebx,1
    mov ecx,SIZEOF target - 1

    call DumpMem
    exit
main ENDP
END main

原文地址:https://www.cnblogs.com/Mayfly-nymph/p/11482983.html