AI摘要

本文介绍了逻辑运算的基本概念和应用,包括或、与、异或、非、左移等运算,并详细解释了计算机如何通过逻辑运算实现加法运算。文章还探讨了寄存器与内存的工作原理,包括寄存器的类型、内存的寻址方式和堆栈的基本概念。最后,文章通过加密和解密的例子展示了逻辑运算在客户端和服务器通信中的应用,并介绍了STOS指令在批量填充内存中的作用。

逻辑运算

或(or  |)

只要有一个为1就是1

1011000101
1001100110
__________
1011100111

与(and  &)

两个都为1才是1

1011000101
1001100110
__________
1001000100

异或(xor ^)

1011000101
1001100110
__________
0010100011


上1下0 只有这样,电路才可以连通

非(not!)

1是0 0是1

1001100110
__________
0110011001

左移(<<)

0010<<0100

计算机如何计算2 + 3

X:0010
Y:0011
xor X Y =  R = 0001

如何判断3+2计算完毕

and X Y = Z = 0010
Z<<0100  根据这个结果是否为0判断计算是否结束
Y:0100
X:0001
xor X Y = R = 0101
X:0001
Y:0100
and = 0000
0000<<1 = 0000   R = 0101

逻辑运算在客户端和服务器加密的应用

客户端:2015

秘钥:54
客户端将数据发送给服务端(加密)
20  15    两个字节

      00100000      
xor   01010100
_____________
      01110100 ->74
      00010101
xor   01010100
_____________
      01000001 ->41

The answer is 7441

服务器:7441(服务器解密过程)

秘钥:54

      01110100
xor   01010100
______________
      00100000->20
      01000001
xor   01010100
______________
      00010101->15

解密数据 = 2015

寄存器与内存

寄存器是最快的(效率高 成本高) 内存比寄存器慢(效率低 成本低)
32位通用寄存器 不用记具体用途 对我们来说他只是一个容器
几个常用的计量单位
byte(字节) = 8Bit
Word(字) = 16Bit
Dword(双字) = 32Bit
通用寄存器的使用(EAX/ECX/EDX/EBX)
MOV/ADD/SUB
mov eax,12345678
add eax,1
mov ecx,2
add eax,ecx
sub eax,3
要加上0x表示十六进制数

内存


每个内存单元的宽度为8个字节
内存单元的编号称之为地址
为什么物理机被称为32位计算机
因为寻址宽度为32位 即8个十六进制数
从0X00000000~0xFFFFFFFF
1k = 1024字节
1m = 1024k
32位的寻址宽度可以存储FFFFFFFF+1的数据

系统已经有一部分的占用,所以内存一般没有理想的那么大

内存的读写

读取内存的值

寻址公式一

MOV EAX,DWORD PTR DS:[0x13FFC4]//从后边地址取值,取32位大小的数据
MOV EAX,DWORD PTR DS:[0x13FFC8]

向内存中写入数据:
MOV DWORD PTR DS:[0x13FFC4].eax
MOV DWORD PTR DS:[0x13FFC8],ebx

获取内存编号:
LEA EAX,DWORD PTR DS:[0X13FFC4]
LEA EAX,DWORD PTR DS:[ESP+8]

DS->数据段  SS->栈段  ES->附加段

lea 取地址编号

寻址公式二:[reg] reg代表寄存器可以是8个通用寄存器中的任意一个

读取内存的值:
MOV ECX.0x13FFD0
MOV EAX,DWORD PTR DS:[ECX]


向内存中写入数据:
MOV EDX.0x13FFD8
MOV DWORD PTR DS:[EDX],0x87654321


获取内存编号:
LEA EAX,DWORD PTR DS:[EDX]
MOV EAX,DWORD PTR DS:[EDX]

寻址公式三:[reg+立即数]

读取内存的值:
MOV ECX,0x13FFD0
MOV EAX,DWORD PTR DS:[ECX+4]


向内存中写入数据:
MOV EDX.0x13FFD8
MOV DWORD PTR DS:[EDX+0xC],0x87654321


获取内存编号:
LEA EAX.DWORD PTR DS:[EDX+4]
MOV EAX,DWORD PTR DS:[EDX+4]

寻址公式四:[reg+reg*{1,2.4,8}]

读取内存的值:
MOV EAX.13FFC4
MOVECX.2
MOV EDX,DWORD PTR DS:[EAX+ECX*4]//只能是1248


向内存中写入数据:
MOV EAX,13FFC4
MOV ECX.2
MOV DWORD PTR DS:[EAX+ECX*4],87654321


获取内存编号:
LEA EAX,DWORD PTR DS:[EAX+ECX*4]

寻址公式五:[reg+reg*{1,2,4,8}+立即数]

读取内存的值:
MOV EAX,13FFC4
MOV ECX.2
MOV EDX,DWORD PTR DS:[EAX+ECX*4+4]


向内存中写入数据:
MOV EAX.13FFC4
MOV ECX.2
MOV DWORD PTR DS:[EAX+ECX*4+4],87654321


获取内存编号:
LEA EAX,DWORD PTR DS:[EAX+ECX*4+2]


堆栈

1、堆栈的本质就是内存。
2、栈是用来存储临时变量,函数传递的中间结果。
3、操作系统维护的,对于“程序员"是透明的。
注:课程里面会用一周的时间来熟悉堆栈。

push esp减小  pop esp增加
作业:
push eax
等于
mov dword ptr ss:[esp-4],eax
sub esp,4

push esp
等于
mov dword ptr ss:[esp-4],esp
lea esp,dword ptr ss:[esp-4] 
或者
mov dword ptr ss:[esp-4],esp
sub esp
pop esp
等于
lea esp,dword ptr ss:[esp+4]
mov esp,dword ptr ss:[esp-4]
与 push 对应的 pop 操作则相反:先降低栈顶指针,再取出数据。
或者
add esp,4
mov esp,dword ptr ss:[esp-4]

STOS(Store String)直译是 “存储字符串”,它的核心作用是:将累加器(AL/AX/EAX/RAX)中的值,存储到 ES:DI(或 ES:EDI/RDI)指向的内存地址中,并根据方向标志位(DF)自动调整 DI/EDI/RDI 寄存器的值,方便连续存储。
简单说,STOS 就是 “把寄存器里的数写到内存里”,专门用于批量填充内存(比如 memset 功能),是串操作指令中最常用的之一。

分别为Stosb  stosw stosd stosq
DF=0(默认,可通过 CLD 指令设置):DI/EDI/RDI 自动递增(向高地址存储);
DF=1(可通过 STD 指令设置):DI/EDI/RDI 自动递减(向低地址存储)。
REP STOS 是 x86 汇编中高效批量填充内存的核心指令:
核心逻辑:ECX 控制次数,DI 指向目标内存,累加器提供填充值,重复执行存储操作;
典型用途:内存清零、批量赋值(如填充 NOP、初始化数据缓冲区);
关键前提:DI 必须指向当前进程的有效内存地址(否则会触发无效内存访问,和你之前 dd eax 的问题本质相同)。

作业


END
本文作者: 文章标题:滴水三期-公开课2
本文地址:https://blog.cvpotato.cn/default/23.html
版权说明:若无注明,本文皆INT3 blog原创,转载请保留文章出处。
最后修改:2026 年 01 月 23 日
如果觉得我的文章对你有用,请随意赞赏