3-DB位 and G位

G(粒度)标志

在64位操作系统中 base段基址和limit限长以及G位就会被取消掉了
因为在32位系统中整体的段描述的范围大小是4GB,而64位的系统,只有32位的段是装不下的,所以就被废掉了.

DPL是权限位

image.png
limit限长是 0xFFFFF 2^20 = 1048576 / 1024 = 1024K = 1M,那么段限长最大为1M。
但是线长不是按照字节来算的,是与G标志位有关。

当G标志位为1时, 是按页来算的,1页有4kB,就是4096个字节
G =1时 : 0xFFFFF *4096(0x1000) = 0xFFFFF000 还是不满足4GB(0xFFFFFFFF)
但由于内存地址的特性,是从0开始计数的,所以 0~0xFFFFF,(0xFFFFF+1)*0x1000 = 10 0000 0000 -1 = 0xFFFFFFFF= 4GB

G位实验

测试修改G位的数值,检验当G=1时,数据是否存的下,当G=0,数据是否会发生异常.
将数据段的段描述符赋值到48的位置
eq 80b99000+48 00cff3000000ffff`
image.png

测试代码

int g_value = 0x100;
int g_value1 = 0;
int main() 
{
	__asm
    {
		mov ax,0x48;
		mov ds,ax;
		mov eax,dword ptr ds:[g_value];
		mov g_value1,eax;
		mov ax,es;
		mov ds,ax;
		
    }
	printf("g_value1 = %x\r\n",g_value1);
	system("pause");
	return 0;
}

G标志位为1,以页为单位,限长大小为4GB,能够将该地址的值写入eax
image.png

image.png
将G位值0,那么00cff3000000ffff就改为004ff3000000ffff
eq 80b99000+48 004ff3000000ffff`
image.png
执行代码后发生c5异常

image.png

总结:

  1. G标志位被称为粒度标志.
  2. 线长不是按照字节来算的,是与G标志位有关.
  3. G=0:段限长以字节为单位.,最大就是1M.
  4. G=1:段限长以页4KB为单位.最大就是4GB.

D/B(默认操作数大小/默认栈指针大小和/或上限)标志

image.png
根据这个段描述符所指的是一个可执行代码段,一个向下扩展的数据段还是一个堆栈
段,这个标志完成不同的功能。
D表示为默认:default 主要与Type有关.
对32位的代码和数据段,这个标志总是被置为1,而16位的代码和数据段,这个标志总是被置为0.
在32位系统中push eax是4个字节,16位系统中,占2个字节.
这是如何区分的呢?

主要由D/B位来决定,如果D/B位为0,那么就认为你的操作数是16位系统,如果D/B位为1,那么你的操作数就是32位系统. 因此它决定你的堆栈寻址空间是16还是32位.

64位系统抛弃了base和limit以及G位
当D/B位的段描述符表示的是代码段时,则改变的是堆栈寻址的默认操作.

  • 可执行代码段 这个标志被称为D标志,它指明该段中的指令所涉及的有效地址值

的缺省位位数和操作符的缺省位位数。如果该标志为1,缺省为32位的地址,32位
或者8位的操作符;若为0,缺省为16位的地址,16位或者8位的操作符。

  • 堆栈段(由SS寄存器所指向的数据段) 这个标志被称为B(big)标志,它为隐含

的栈操作(如push,pop和call)确定栈指针值的位位数。如果该标志为1,则使用
的是32位的栈指针,该指针放在32位的ESP寄存器中;若该标志为0,则使用的是放
在16位 SP寄存器中的16位的栈指针。

实验:

目的:修改代码段CS,检验D/B位,置1或置0时,push eax ,查看堆栈寻址空间的变化
image.png

当D/B位为1时

CS的段选择子为001B,段描述符为00cffb00'0000ffff

c : 1100

image.png
此时给eax赋值0x12345678,再将eax push压入堆栈中
此时栈顶为0031FDBC
image.png
操作完后,栈顶的数值变为了0031FDB8,0031FDBC-0031FDB8 = 4字节
image.png

当D/B位为0时

CS的段选择子为001B,段描述符为00cffb00'0000ffff

c : 1000
image.png
修改CS段为0048,那么使用jmp跳到0x48:009A13E0,再使用push eax 压入堆栈
此时ESP为0012FD5C
image.png
此时ESP为0012FD5A, 0012FD5C - 0012FD5A = 2字节
image.png
当D/B位的段描述符表示的是代码段时,则改变的是堆栈寻址的默认操作.
以上在软件上的修改只是对该进程有效,当我们进入到内核中时,无论你是系统调用还是发生异常,系统第一步会检查各个段,并修复回原值,所以以上修改并不会导致系统崩溃.

当Type为普通数据段时

堆栈段

当我们的SS段发生改变,那么寄存器就会变成16位了,比如ESP就会变成SP了

最小的内存0-0xFFFF是不能被访问的.
image.png
所以当我们的SS段发生改变的时候,ESP寄存器变成了16位,此时压栈是会导致程序崩溃.

我们将008ffb000000ffff`段描述符改为数据段,该怎么改?

image.png
当Type的数值07之间就是数据段,815是代码段.
所以将008ff2000000ffff`,此时该段权限是可读可写但没有访问的权限.

实验操作

eq 80b99000+48 008ff2000000ffff`
image.png

image.png
执行完后发现
image.png
刚才的Type改为了2,执行完后却变成了3
原因是当我们的数据段被载入一次后,access这个标志位是由CPU自动置位的,说明这个段被用过.
这样可以区别该段是否被用过.

当我们使用堆栈段的时候就会发生C05异常
image.png

向下扩展的数据段

如果该堆栈段为一个向下扩展的数据段,B标志还确定了该堆栈段的地址上界。

向下扩展的数据段 这个标志称为B标志,它确定了该段的地址上界。
如果该标志为1,段地址上界为FFFFFFFF(4GB);若该标志为0,段地址上界为FFFF(64KB)。
image.png
image.png

测试向下拓展Type为6
image.png
image.png
eq 80b99000+48 008ff6000000ffff`
image.png

image.png
程序发生异常

image.png

测试限长为0的情况 ,DB为1时
eq 80b99000+48 00c0f60000000000`
程序没有发生异常
image.png

D位描述的是代码段,改变默认的寻址操作数
B位把整个代码段或者整个数据段变成16位的寄存器以及地址,限制了limit

非一致 、一致的代码段
image.png

使用一致代码段会有页的限制,除非我们运行在整个段里面。

保护模式分为两种
段页模式
纯段模式(没有页的保护)

总结:

1.Type为代码段时,这个标志被称为D标志
D/B为1:表示默认为32位的地址
D/B为0:表示默认为16位的地址
2.Type为普通数据段时,这个标志被称为B标志;分为堆栈段和向下扩展的数据段两种情况
堆栈段
D/B为1:使用的是32位的栈指针(ESP)
D/B为0:使用的是16位的栈指针(SP)
向下扩展的数据段
D/B为1:段地址上限为FFFFFFFF
D/B为0:段地址上限为FFFFF

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
clear all; Tx_n = 2; Rx_n = 2; %---------------SNR vector------------- SNRindB = 2:1:10; SNR = 10.^(SNRindB/10); %------------modulation----------------- L = 20000; BitPerSymbol = 2; s0 = randi(1,1,L); h_1 = pskmod('M',2^BitPerSymbol,'gray','InputType','Bit'); s = modulate(h_1,s0.').'; %-------------seperation-------------- s1 = zeros(Tx_n,length(s)); for ii = 1:Tx_n:(length(s)-1) %stbc s1(1,ii) = s(ii); s1(2,ii) = s(ii+1); s1(1,ii+1) = conj(s(ii+1)); s1(2,ii+1) = -conj(s(ii)); end L1 = length(s1(1,:)); %----------noise and channel-------------- S = zeros(2, 2); S1 = zeros(1, L1); rx = zeros(L, 1); BER = zeros(length(SNR), 1); SER = zeros(length(SNR), 1); for ii = 1:length(SNR) sigma = 1/(sqrt(2*SNR(ii))); for iii = 1:2:L1-1 noise = sigma*(randn(Rx_n,1)+1i*randn(Rx_n,1)); H = sqrt(0.5)*(randn(Rx_n, Tx_n) + 1i*randn(Rx_n, Tx_n)); %----------add noise------------------------ R1 = H*s1(:,iii)+noise; %接收信号1,Rx_n * 1 R2 = H*s1(:,iii+1)+noise; %接收信号2,Rx_n * 1 %----------receive MMSE------------------- hh = H(:,1).*conj(H(:,1)) + H(:,2).*conj(H(:,2)); S_t1 = conj(H(:,1)).*R1-H(:,2).*conj(R2); S_t2 = conj(H(:,2)).*R1+H(:,1).*conj(R2); S(:,1) = S_t1./hh; S(:,2) = S_t2./hh; for si = 1:1:Rx_n S1(1,iii) = S1(1,iii) + S(si,1); S1(1,iii+1) = S1(1,iii+1) + S(si,2); end S1(1,iii) = S1(1,iii)/Rx_n; S1(1,iii+1) = S1(1,iii+1)/Rx_n; end h_2 = modem.pskdemod('M', 2^BitPerSymbol,'SymbolOrder','gray', 'OutputType', 'Bit'); rx = demodulate(h_2,S1.'); remod = modulate(h_1, rx); %------------calculate ber--------------------------- SER(ii,:) = symerr(remod.',s)/L1; BER(ii,:) = biterr(rx.',s0)/L; end semilogy(SNRindB,BER,'g-^'); hold on; semilogy(SNRindB,SER,'m-^'); grid on; xlabel('SNR(dB)'); ylabel('BER'); title('STBC SNR-BER curve'); legend('BER 2x1','SER 2x1','BER 2x2','SER 2x2');代码有误,帮忙修改一下
05-30

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

黑桃鱼

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值