微机原理
8086寻址方式⭐
形成指令地址或操作数地址的方式,称为寻址方式。
8086CPU的寻址分为两类,即指令寻址方式和数据寻址方式。
1.立即寻址
指令的操作数(地址码)字段直接给出操作数本身。
例:MOV AX,251
MOV AL,‘5’
MOV AL,0E8H
MOV AX,2346H
其中,251、‘5’、0E8H、2346H均为立即数
※立即数不能放入段寄存器中。 (×)MOV CS,251
立即数只能做源操作数。 (×)MOV 3,AL
源、目的操作数的字长必须一致。 (×)MOV AH, 3064H
立即寻址不能用于单操作数指令。
2.寄存器寻址
操作数在CPU内部的通用寄存器中,指令指定寄存器名。
8位通用寄存器:AH、AL、BH、BL、CH、CL、DH、DL
16位通用寄存器:AX、BX、CX、DX、SI、DI、BP、SP
段寄存器:CS、DS、SS、ES
FLAGS标志寄存器
例:
其中,CL、DL、AX、BX就是寄存器寻址方式。
※
CS(代码段寄存器)不能作目的操作数。
(×)MOV AL,BX (×)MOV AX,BL
(×)MOV CS,DS
3.存储器寻址
必须求物理地址!
既可用于DST,也可用于SRC,但不能同时使用, 用方括号对[]表示存储器寻址。
(1)直接寻址
EA(有效地址)=DISP(偏移量)
地址表达式 / [地址表达式] / [数字表达式]
直接寻址方式默认的段寄存器是DS。
例——P88~90
(2)寄存器间接寻址
EA=[BX]/[BP]/[SI]/[DI]
BX、BP为基址寄存器;SI、DI为变址寄存器。
如果指令中指定的寄存器是BX、SI、DI,则操作数默认在数据段中,取DS寄存器的值作为操作数的段地址值;如果指令中指定的寄存器是BP,则操作数默认在堆栈段中,取SS寄存器的值作为操作数的段地址值。
例:
※
(3)寄存器相对寻址
EA=[BX]/[BP]/[SI]/[DI]+DISP
例:三种等价的形式
(4)基址加变址寻址
EA=[BX]/[BP]+[SI]/[DI]
(5)相对基址加变址寻址
EA=[BX]/[BP]+[SI]/[DI]+DISP
位移量[基址寄存器][变址寄存器]
[基址寄存器+变址寄存器+位移量]
4.I/O端口寻址
计算机网络原理
TCP和UDP的区别,哪个效率更高?
UDP效率更高。
TCP的优点: 可靠、稳定
稳定的原因:稳定TCP的可靠体现在TCP在传递数据之前,会有三次握手来建立连接,而且在数据传递时,有确认、窗口重传、拥塞控制机制,在数据传完后,还会断开连接用来节约系统资源。
TCP的缺点: 慢,效率低,占用系统资源高,易被攻击。
TCP效率低的原因: 在传递数据之前,要先建连接,这会消耗时间,而且在数据传递时,确认机制、重传机制、拥塞控制机制等都会消耗大量的时间,而且要在每台设备上维护所有的传输连接,事实上,每个连接都会占用系统的CPU、内存等硬件资源。 而且,因为TCP有确认机制、三次握手机制,这些也导致TCP容易被人利用,实现DOS、DDOS、CC等攻击。
UDP的优点: 效率高,比TCP稍安全。
不稳定的原因:因为UDP没有TCP那些可靠的机制,在数据传递时,如果网络质量不好,就会很容易丢包。
UDP的缺点:不可靠,不稳定。
效率高的原因: UDP没有TCP的握手、确认、窗口、重传、拥塞控制等机制,UDP是一个无状态的传输协议,所以它在传递数据时非常快。没有TCP的这些机制,UDP较TCP被攻击者利用的漏洞就要少一些。但UDP也是无法避免攻击的,比如:UDP Flood攻击等等。
数据结构
哈希表
b站的哈希表教学视频讲得很清楚→
带你快速理解 哈希表(散列表)的运作原理
树
无序树、有序树
二叉树、满二叉树、完全二叉树、平衡二叉树(AVL树)、二叉搜索树、霍夫曼树、红黑树
B树、B+树、B*树、R树
字典树、后缀树
代码题
LeetCode #34. 在排序数组中查找元素的第一个和最后一个位置
从前往后遍历一遍,用两个变量记录第一次和最后一次遇见 target 的下标,这很简单,时间复杂度为O(n),但没有利用到数组升序排列的条件。
对此进行优化,可用二分查找的方法,时间复杂度为O(log n)。
class Solution {
public:
int binarySearch(vector<int>& nums, int target, bool lower) {
int left = 0, right = (int)nums.size() - 1, ans = (int)nums.size();
while (left <= right) {
int mid = (left + right) / 2;
if (nums[mid] > target || (lower && nums[mid] >= target)) {
right = mid - 1;
ans = mid;
} else {
left = mid + 1;
}
}
return ans;
}
vector<int> searchRange(vector<int>& nums, int target) {
int leftIdx = binarySearch(nums, target, true);
int rightIdx = binarySearch(nums, target, false) - 1;
if (leftIdx <= rightIdx && rightIdx < nums.size() && nums[leftIdx] == target && nums[rightIdx] == target) {
return vector<int>{leftIdx, rightIdx};
}
return vector<int>{-1, -1};
}
};