网页新闻贴吧知道音乐图片视频地图文库
进入贴吧全吧搜索吧内搜索

 
 
 
日一二三四五六
       
       
       
       
       
       

签到排名:今日本吧第个签到,

本吧因你更精彩,明天继续来努力!

本吧签到人数:0

一键签到
成为超级会员,使用一键签到
一键签到
本月漏签0次!
0
成为超级会员,赠送8张补签卡
如何使用?
点击日历上漏签日期,即可进行补签。
连续签到:天  累计签到:天
0
超级会员单次开通12个月以上,赠送连续签到卡3张
使用连续签到卡
07月10日漏签0天
fx-es(ms)吧 关注:11,643贴子:255,100
  • 看贴

  • 图片

  • 精品

  • 视频

  • 游戏

  • 1 2 下一页 尾页
  • 70回复贴,共2页
  • ,跳到 页  
<<返回fx-es(ms)吧
>0< 加载中...

【技术】内部数值存储研究

  • 只看楼主
  • 收藏

  • 回复
  • masmyc
  • 9860GII
    12
字符表镇楼:


帖子会在接下来的几天内慢慢继续更新,请各位别着急。


  • 突发规划
  • TI-84+CE
    13
一个有姿势的二楼


  • masmyc
  • 9860GII
    12
@骆奕扬 曾经说过楼主善于利用M值。并且发明了魔数法来辅助拼字。下面来谈谈这样的数是怎么构造出来的。


楼楼的技术比不上本吧各位大神。吧内也有其他谈内部数值存储的帖子。但是我希望我这篇帖子更清晰。


  • 突发规划
  • TI-84+CE
    13
插


  • masmyc
  • 9860GII
    12
此帖子以 fx-991ES PLUS 为参考型号。因为楼楼用的就是这个型号。


一、有哪些数值存储方式


根据目前的研究,991+一共有浮点、分数、根式、复数、指针、特殊值这五种存储方式。


浮点:±a×10^n 其中 0≤a<10 -99≤n≤99。
分数:±a/b 其中a和b以十进制表示的位数之和不超过9。
根式:±(a√(b)+c√(d))/e 目前楼主对于 a b c d e 的取值范围不太了解。但是 a b c d e 都可以取 0 或者 1。
复数:±a×10^n±b×10^mi 其中 0≤(a,b)<10 -99≤(n,m)≤99。
指针:目前已知 MatA/VctA (0x60) MatB/VctB (0x61) MatC (0x62) MatAns/VctAns (0x63)。
特殊值:目前已知 ERROR (0xF3)。


  • 402zhouxuefeng
  • 5800P
    10
顶


  • linym66
  • TI-84+
    11
插


  • masmyc
  • 9860GII
    12
二、变量存在哪?


目前发现变量 M Ans A B C D E F X Y 是依次存储的,每一个变量占用10字节。
M 的存储位置是基本溢出缓冲区便宜量 +0xCA。也就是紧挨着随机数种子(即不稳定字符,占2字节)存储的。
变量的很多存储方式是用 BCD 码来存储。也就是说这一系列计算器的计算实际上是用十进制的,而不是二进制。这也是为什么这一系列计算器在做大量运算的时候比较慢,但是却不会产生类似计算机 IEEE 浮点数在做二进制运算的时候产生的误差。
复数的实部存储在我所说的地方,而虚部存储在另外的地方,也是各占用10字节(这可以从 CMPLX 溢出模式的种种异常现象研究出来,参考楼主的《【991+】A^0法溢出r!比M^0法节省57%按键次数!》)。这片存储区域在退出 CMPLX 的时候可能会被别的模式的存储区域复写。
矩阵和向量的内容也是存储在另外的地方的,并且那地方和 COMP 模式的历史记录缓冲区貌似共用内存(在 COMP 模式爆出矩阵后输入很长的算式按等号会导致矩阵内容爆出 ERROR,参考楼主的《【991+】不进乱点模式爆矩阵!》)。这片存储区域在退出 MATRIX 的时候会把 MatA/VctA MatB/VctB MatC 清零,但是 MatAns/VctAns 不清,在进入别的模式的时候可能会被覆盖。


  • 突发规划
  • TI-84+CE
    13
插


  • masmyc
  • 9860GII
    12
(顺便提一下)为什么计算器要分模式?


计算器分模式可不是为了在卖的时候能够体现出自己功能多,而是为了节省内存,同时可以实现开关不同的模式来实现同一个固件在不同型号计算器下有不同的功能(这也是为什么会有软升级)。
其实,如果不分模式,COMP CMPLX BASE-N 等模式是可以挤在一起的。MATRIX VECTOR 也是可以的。STAT TABLE 就更不用说了。但是众所周知,计算器的内存很有限。这么多功能,全部载入 RAM 中是不可能的。于是就采用了当年 MS-DOS 应用程序采用的一个技术——Overlay。也就是不同的模式共用一块内存。载入新模式的时候覆盖旧的内存。
分模式也有利于降低开发难度,减少 bug。多种型号的硬件共用同一个固件并打开不同的模式也可以降低开发成本(程序员的工资比流水线工人的工资高啊)。


如何利用这种功能?
我们在某些特定的溢出状态下,需要了解哪些内容共用一块内存来构造合适的数值进行下一步操作。类似于攻击计算机操作系统,需要对内存布局和内核架构有一定了解,研究计算器的异常也需要对内存有一定了解。对于 82ES 等型号,官方公布了模拟器,可以用模拟器配合 WinHex 来研究;而对于 991ES PLUS 等型号,只有摸黑试了,楼主在 1L 的字符表正是用刷不稳定字符的方法得到的。


  • masmyc
  • 9860GII
    12
三、白值是怎么回事?


白值不仅仅是一种情况。只要是无法显示的数值都可能变成白值/ERROR/死机。当然 ERROR 也可以是计算器预料之中的 0xF3 特殊值。
比如 5L 说到浮点 ±a×10^n 的取值范围是 0≤a<10 -99≤n≤99。如果 a 不满足这个取值范围,则会导致白值。如果 n 不满足,可能会被截头或溢出或死机。


  • masmyc
  • 9860GII
    12
下面一帖说浮点的存储。楼楼先慢慢码字,你们随便插楼,今天如果码好了就今天发,如果今天没有码好就明天发。


  • 突发规划
  • TI-84+CE
    13
插


  • 361187493
  • 9860GII
    12
ls插了四次了


  • Fin2014unique
  • 5800P
    10
技术贴


  • lolo_often
  • TI-84+
    11
后排留名


  • 突发规划
  • TI-84+CE
    13
居然精了?!


  • masmyc
  • 9860GII
    12
自然语言的解释还没有码好,预计明天发。


在《求问关于M的事情》一贴中 @lhy7715 提到可否用 C 语言来描述一下,下面放代码:


struct storage_area {
unsigned long long int padding; /* off+0xC0 */
unsigned /* little_endian */ short int rand_seed; /* off+0xC8 */
struct value_var M, Ans, A, B, C, D, E, F, X, Y; /* off+0xCA */
};


struct value_var {
unsigned char data[8]; /* BCD code, magnitude */
unsigned char exp; /* BCD code, two's complement */
unsigned char sign;
}


#define odd(x) ((x) & 0x1)
#define bcd2int(bcd) ((((bcd) >> 4) & 0xf)*10+((bcd) & 0xf))


#define get_value_var_type(x) ((x).data[0] >> 4)
#define get_value_var_digit(x, digit_no) ((x).data[(digit_no)/2] >> (odd((digit_no)) ? 0 : 4) & 0xF) /* 1 <= digit_no <= 15 */


/* Values for value_var.sign */
#define VALUE_VAR_SIGN_POS_NEG 0x0 /* 0 <= x < 1 */
#define VALUE_VAR_SIGN_POS_POS 0x1 /* x > 1 */
#define VALUE_VAR_SIGN_NEG_NEG 0x5 /* -1 < x < 0 */
#define VALUE_VAR_SIGN_NEG_POS 0x6 /* x <= -1 */


看不懂的等我的自然语言详解。


  • masmyc
  • 9860GII
    12
提示:本贴中的内存偏移量是从用 X=∑(X,1,2 进入标准溢出模式时的光标位置算起的,如果需要从第一输入缓冲区开始计数,请加上 0x09,如果从第二输入缓冲区开始计数,请减去 0x5C。


四、数值存储方式扩充


每一个变量占用10个字节,在5L中我有一些介绍。但是存储方式是怎么指明的呢?这就要看低一个字节的高4位,我将其称为变量类型域。
比如令 M=3.14159265358979 此时内存偏移量 +0xCA 处的内容为:
03 14 15 92 65 35 89 79 00 01
那么变量类型域就是 03 中的 0,它代表浮点。


5L提到了6种类型,但是复数变量使用单独的存储空间,并且那个存储空间无法在标准溢出模式中读取,所以这里不讨论。


剩下来五种类型的变量类型域为:
0x0: 浮点
0x2: 分数
0x4: 浮点的度秒分表示
0x6: 矩阵或向量的指针
0x8: 根式
0xF: 特殊值(目前已知 ERROR)


  • masmyc
  • 9860GII
    12
五、浮点格式


十个字节,如下定义:


字节1,高4位:变量类型域,应为 0x0。
字节1,低4位:第一位十进制有效数字。
字节2,高4位:第二位十进制有效数字。
字节2,低4位:第三位十进制有效数字。
……
字节8,低4位:第十五位十进制有效数字。
字节9:指数,用BCD解码,负数用反码,稍后解释。
字节10:符号位:
0x00:0≤X<1
0x01:X≥1
0x05:-1<X<0
0x06:X≤-1


  • masmyc
  • 9860GII
    12
下面我来举例子:


令 M=5.42694682881413×10^81
内存为 05 42 69 46 82 88 14 13 81 01


令 M=4.55070183730897×10^-32
内存为 04 55 07 01 83 73 08 97 68 00 (注意 68=100-32,正所谓反码表示负数)


令 M=-7.65120911691×10^57
内存为 07 65 12 09 11 69 10 00 57 06 (注意末位补零)


令 M=-7.46426841128546×10^-18
内存为 07 46 42 68 41 12 85 46 82 05


  • masmyc
  • 9860GII
    12
六、浮点的度秒分表示


相当于输入对应的数值再按下度分秒按钮的效果。
如 41 50 00 00 00 00 00 00 00 01 表示 1度30分0秒
这里就不再赘述了


  • masmyc
  • 9860GII
    12
七、分式


字节1,高4位:变量类型域,应为 0x2。
从字节1的低4位到字节8的低4位是数值位,稍后解释。
字节9依然是指数。
字节10依然是符号位。


关于数值位,下面举一个例子:
21 A3 00 00 00 00 00 00 00 01,此时 M=1/3
也就是说把数值位用 BCD 码解码后从 A 处分隔。
上述的例子分成了 1 和 3 两个部分。
那么就表示 1/3。
如果有两个 A,那么代表带分数。
如 21 A2 A3 00 00 00 00 00 00 01,此时 M=1+2/3
但是,经过测试 fx-82ES PLUS 优先采取带分数存储分数值,fx-991ES PLUS 优先采取假分数存储分数值。存储时采取带分数还是假分数不影响显示的效果。
如果有超过两个的 A,会导致不可预料的异常。


关于指数,我测试了多种组合,发现符号位取 0x01 时,指数位可以取 0x00 至 0x0F 的任意值。并且取值会导致分数的分子或分母含有小数点或者采取科学计数法。但是字节9的具体含义还需要各位继续发掘。


(fx-82ES PLUS 的存储方式我可以通过模拟器得到,而 fx-991ES PLUS 的存储方式只有通过基本溢出法读取)


  • masmyc
  • 9860GII
    12
八、矩阵或向量的指针


第一个字节决定了指向的目标。剩下9个字节未发现用处。
0x60 代表 MatA/VctA
0x61 代表 MatB/VctB
0x62 代表 MatC
0x63 代表 MatAns/VctAns


这也是为什么前人在异常模式下在 M Ans A B C D E F X Y 中存储矩阵或者向量。


光有这个变量没有用,还需要对应的矩阵有定义。方法是进入 MATRIX 模式或 VECTOR 模式,用 Dim 菜单定义某矩阵。或者做矩阵运算,使矩阵存储到 MatAns 中。


MatA/VctA MatB/VctB MatC 三个矩阵会在退出 MATRIX 模式或 VECTOR 模式的时候清空,所以为了不让其清空可以采取特殊的方法来切换模式。这里给大家留思考题,需要5次按键。


关于利用这种类型的变量,可以参考楼主的《【991+】不进乱点模式爆矩阵!》一贴。


  • AOU_CHEN
  • JP900
    9
顶


  • masmyc
  • 9860GII
    12
⑨、根式


先修正一下5L的内容。根式的内部表示方法其实是 ±a/b*√(c)±d/e*√(f)。
其中 0≤(a,b,d,e)≤99 0≤(c,f)≤999。
也就是说两项可以用不同的分母,显示的时候会自动通分。


十个字节如下分布:
8f ff dd ee 0c cc aa bb rr ss
8 是变量类型域。
0 是未用的一个域,通常情况下为 0,目前发现人为写入任何值不影响结果。
其中 aa bb ccc dd ee fff 分别代表 BCD 编码后的 a b c d e f 值。
rr 代表 ±a/b*√(c) 的符号位,ss 代表 ±d/e*√(f) 的符号位。依然是 0x01 或者 0x05。
并且一般情况下计算器储存是会让 c≤f。但是显示的时候会让较大的根式在左边。


比如当计算器显示成 (√(6)-√(2))/4 时,内部的储存是:
80 02 01 04 00 06 01 04 01 05


  • masmyc
  • 9860GII
    12
十、特殊值 ERROR


就像计算机浮点数有三个特殊值 Infinity -Infinity NaN 一样,fx-ES PLUS 系列计算器有一个特殊值,那就是 ERROR。
第一个字节取 0xF3,其他字节没有用处。


自然状态下 ERROR 可以用如下方法得到:


方法一:TABLE 法。
进入 TABLE 模式,输入函数式 f(X)=0,Start 输入 0,Stop 输入 9.99999999999999×10^99,Step 输入 5×10^99。输出的表格第二行显示 X。此时变量 X 值为 ERROR。


方法二:积分法。(参见楼主的《【991+】积分法溢出ERROR,不用再TABLE了!》一贴)
在 COMP 模式输入 M=∫(1,M,9.99999999999999×10^99),然后按 CALC,输入初值 M=0。


ERROR 值可以用来触发 CMPLX 溢出模式。


  • masmyc
  • 9860GII
    12
订正28L的句子:
并且一般情况下计算器储存是会让 c≤f。但是显示的时候会让较大的根式在左边。


改成:
并且一般情况下计算器储存是会让 f≤c。但是显示的时候会让较大的根式在左边。


  • HEAVEN4499
  • TI-84+
    11
楼主威武荡漾


  • masmyc
  • 9860GII
    12
十一、如何利用变量值辅助拼字(魔数法)


这里就举楼主自己的例子吧:《【991+】【新手向】一步步教你打 I love you》的9L中使用了这两个变量:
M=1.4920313076652×10^79
Ans=1.7521202020202×10^-69


下面来转换成内部的存储结构:
M 为 01 49 20 31 30 76 65 20 79 01
Ans 为 01 75 21 20 20 20 20 20 31 00


转换成字符串为:"\x01I 10ve y\x01\x01u! 1"
也就是说我们利用这两个数值产生了13个目标字符。这13个目标字符中有10个字符是键盘上没有对应按键的字符。
也就是说使用辅助变量值可以减少刷不稳定字符的数量。


那么一共有 M Ans A B C D E F X Y 十个变量,每一个变量都可以辅助拼字。总共可用字节有 80 字节,完全可以满足四行拼字的 64 字节的需要。


其实在基本溢出模式下是无法访问到 D 后面的变量区域的(最多只能到达偏移量 +0xFF 的地方),但是可以通过删除来使后面的内容移动到前面。但是字符串复制是遇到 0x00 就会停止,所以要保证存储的每一个变量大于等于 1 或小于 0,并且填满所有有效数字。


但是魔数法也有弊端,那就是只能表示 99 个字符,涵盖 34 个大小写字母,10 个阿拉伯数字,空格(0x20)、感叹号(0x21)这两个常用标点。所以魔数法只能够起到辅助作用,不能代替刷不稳定字符。


登录百度帐号

扫二维码下载贴吧客户端

下载贴吧APP
看高清直播、视频!
推荐应用
  • 蓝钻
  • t豆娱乐城
  • 斗地主
  • 食神争霸
  • 添加应用
应用中心应用礼包
  • 贴吧页面意见反馈
  • 违规贴吧举报反馈通道
  • 贴吧违规信息处理公示
  • 1 2 下一页 尾页
  • 70回复贴,共2页
  • ,跳到 页  
<<返回fx-es(ms)吧
分享到:
©2017 Baidu贴吧协议|吧主制度|意见反馈|网络谣言警示