明经CAD社区

 找回密码
 注册

QQ登录

只需一步,快速开始

搜索
查看: 3554|回复: 18

[经验] FAS 20号指令的深入研究

  [复制链接]
发表于 2020-3-19 16:35 | 显示全部楼层 |阅读模式
本帖最后由 baitang36 于 2020-3-19 19:54 编辑

      看了tryhi大侠的精华贴 《定义真正意义的可选参数》(http://bbs.mjtd.com/thread-181052-1-1.html)受益匪浅,原来这个不起眼的指令竟然蕴藏玄机。文中对20号指令(十六进制14h)四个参数的作用是这样描述的:
第一字节:表示参数数量+无名变量的数量之和
第二字节:表示允许的最低参数数量
第三字节:表示大参数个数
第四字节:只有00和01两种,00表示为有限参数(默认情况下必然为00),01表示无限参数
经过试验,第二字节和第三字节的描述非常准确,就不做进一步研究了。下面重点研究第一和第四个字节。
用od附加acad.exe进程,跟踪一下14h指令的执行过程,发现相关参数的处理代码如下:(不懂汇编语言的朋友请跳过这一小段代码,直接看后面的结论)
          movzx ax, byte ptr [edi+esi+03]     ;第四个字节
          movzx cx, byte ptr [edi+esi]        ;第一个字节
          and ax, FFFE                        ;第四个字节最低位清零
          shl ax, 07                          ;左移7位,取第四个字节的高七位
          or ax, cx                           ;与第一位相加
          movzx ecx, ax                       ;只保留低16位
          test cx, cx                         ;判断 aa和dd是否为零
          je 574989AC                         ;如为零,跳转到地址574989AC
从上面代码可以看出,第一字节和第四字节不是独立的,是组合在一起使用的。
第四个字节被分成了两部分,一部分和第一字节组合,左移7位与第一字节进行or运算。另一部分,就是最低位的0和1,用来表示有限参数和无限参数。
也就是说,第四字节的高7位是和第一字节组合使用,最低位单独使用。
这样第一个字节和第四个字节组合起来能表示的数值范围是十六进制0-7FFFH,也就是十进制0-32767.
这个数字是做什么用的呢?tryhi大侠认为是表示参数数量+无名变量的数量之和,和晨语探讨,他也这么认为。
我经过跟踪和试验,发现它是函数在初始化时需要清除的无名变量个数,被清除的无名变量内容会变成nil,没有被清除的还是原来的值。
如果程序中要使用无名变量,第一个字节和第四个字节不能同时为0,否则会出现0xC00000005冲突,导致程序不能执行。

结论,20号指令的格式如下:(十六进制)
14 aa bb cc dd
其中: bb表示允许的最低参数个数,如果调用这个函数时参数个数小于这个值,程序出错,显示参数太少。
       cc表示允许的最大参数个数,如果调用这个函数时参数个数大于这个值,程序也会出错,显示参数太多。
       dd的最低位如果是1表示参数是个表,也就是无限参数,如果是0,不是表,参数是有限的。对于是否有限来说,254和0是一样的,255和1效果一样。
       aa和dd的高7位组合,数值表示程序初始化时需要清除掉的无名变量个数,范围是0-32767。举个例子,如果想表示255个,那就是aa=255,dd=0或1。
如果想表示256,那aa=00,dd=2或3; 2表示有限参数,3表示无限参数。
14h指令的反汇编代码见附件,不懂asm的请不要浪费币:-) 。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册

x

评分

参与人数 2明经币 +2 收起 理由
xinxirong + 1 大海也是神人,没有baitang36分析原理,哪.
tryhi + 1 这才是真大神啊!

查看全部评分

"觉得好,就打赏"
还没有人打赏,支持一下
发表于 2020-9-24 14:08 | 显示全部楼层
本帖最后由 Aries 于 2020-9-24 14:19 编辑
KO你 发表于 2020-9-22 01:11
编译成FAS麻烦你发上来咯,谢谢

能不能给我一个币

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册

x

评分

参与人数 2明经币 +2 收起 理由
baitang36 + 1 很给力!
KO你 + 1 赞一个!

查看全部评分

回复 支持 1 反对 0

使用道具 举报

 楼主| 发表于 2020-3-20 09:24 | 显示全部楼层
本帖最后由 baitang36 于 2020-3-20 09:29 编辑

(defun ttt (Arg000 Arg001 Arg002 Arg003 Arg004 Arg005 Arg006 Arg007 Arg008 Arg009 Arg010 Arg011 Arg012 Arg013 Arg014 Arg015
            Arg016 Arg017 Arg018 Arg019 Arg020 Arg021 Arg022 Arg023 Arg024 Arg025 Arg026 Arg027 Arg028 Arg029 Arg030 Arg031
            Arg032 Arg033 Arg034 Arg035 Arg036 Arg037 Arg038 Arg039 Arg040 Arg041 Arg042 Arg043 Arg044 Arg045 Arg046 Arg047
            Arg048 Arg049 Arg050 Arg051 Arg052 Arg053 Arg054 Arg055 Arg056 Arg057 Arg058 Arg059 Arg060 Arg061 Arg062 Arg063
            Arg064 Arg065 Arg066 Arg067 Arg068 Arg069 Arg070 Arg071 Arg072 Arg073 Arg074 Arg075 Arg076 Arg077 Arg078 Arg079
            Arg080 Arg081 Arg082 Arg083 Arg084 Arg085 Arg086 Arg087 Arg088 Arg089 Arg090 Arg091 Arg092 Arg093 Arg094 Arg095
            Arg096 Arg097 Arg098 Arg099 Arg100 Arg101 Arg102 Arg103 Arg104 Arg105 Arg106 Arg107 Arg108 Arg109 Arg110 Arg111
            Arg112 Arg113 Arg114 Arg115 Arg116 Arg117 Arg118 Arg119 Arg120 Arg121 Arg122 Arg123 Arg124 Arg125 Arg126 Arg127
            Arg128 Arg129 Arg130 Arg131 Arg132 Arg133 Arg134 Arg135 Arg136 Arg137 Arg138 Arg139 Arg140 Arg141 Arg142 Arg143
            Arg144 Arg145 Arg146 Arg147 Arg148 Arg149 Arg150 Arg151 Arg152 Arg153 Arg154 Arg155 Arg156 Arg157 Arg158 Arg159
            Arg160 Arg161 Arg162 Arg163 Arg164 Arg165 Arg166 Arg167 Arg168 Arg169 Arg170 Arg171 Arg172 Arg173 Arg174 Arg175
            Arg176 Arg177 Arg178 Arg179 Arg180 Arg181 Arg182 Arg183 Arg184 Arg185 Arg186 Arg187 Arg188 Arg189 Arg190 Arg191
            Arg192 Arg193 Arg194 Arg195 Arg196 Arg197 Arg198 Arg199 Arg200 Arg201 Arg202 Arg203 Arg204 Arg205 Arg206 Arg207
            Arg208 Arg209 Arg210 Arg211 Arg212 Arg213 Arg214 Arg215 Arg216 Arg217 Arg218 Arg219 Arg220 Arg221 Arg222 Arg223
            Arg224 Arg225 Arg226 Arg227 Arg228 Arg229 Arg230 Arg231 Arg232 Arg233 Arg234 Arg235 Arg236 Arg237 Arg238 Arg239
            Arg240 Arg241 Arg242 Arg243 Arg244 Arg245 Arg246 Arg247 Arg248 Arg249 Arg250 Arg251 Arg252 Arg253 Arg254 /            a
           )
  (setq a 0)
  (foreach x (list
               Arg000 Arg001 Arg002 Arg003 Arg004 Arg005 Arg006 Arg007 Arg008 Arg009 Arg010 Arg011 Arg012 Arg013 Arg014 Arg015
               Arg016 Arg017 Arg018 Arg019 Arg020 Arg021 Arg022 Arg023 Arg024 Arg025 Arg026 Arg027 Arg028 Arg029 Arg030 Arg031
               Arg032 Arg033 Arg034 Arg035 Arg036 Arg037 Arg038 Arg039 Arg040 Arg041 Arg042 Arg043 Arg044 Arg045 Arg046 Arg047
               Arg048 Arg049 Arg050 Arg051 Arg052 Arg053 Arg054 Arg055 Arg056 Arg057 Arg058 Arg059 Arg060 Arg061 Arg062 Arg063
               Arg064 Arg065 Arg066 Arg067 Arg068 Arg069 Arg070 Arg071 Arg072 Arg073 Arg074 Arg075 Arg076 Arg077 Arg078 Arg079
               Arg080 Arg081 Arg082 Arg083 Arg084 Arg085 Arg086 Arg087 Arg088 Arg089 Arg090 Arg091 Arg092 Arg093 Arg094 Arg095
               Arg096 Arg097 Arg098 Arg099 Arg100 Arg101 Arg102 Arg103 Arg104 Arg105 Arg106 Arg107 Arg108 Arg109 Arg110 Arg111
               Arg112 Arg113 Arg114 Arg115 Arg116 Arg117 Arg118 Arg119 Arg120 Arg121 Arg122 Arg123 Arg124 Arg125 Arg126 Arg127
               Arg128 Arg129 Arg130 Arg131 Arg132 Arg133 Arg134 Arg135 Arg136 Arg137 Arg138 Arg139 Arg140 Arg141 Arg142 Arg143
               Arg144 Arg145 Arg146 Arg147 Arg148 Arg149 Arg150 Arg151 Arg152 Arg153 Arg154 Arg155 Arg156 Arg157 Arg158 Arg159
               Arg160 Arg161 Arg162 Arg163 Arg164 Arg165 Arg166 Arg167 Arg168 Arg169 Arg170 Arg171 Arg172 Arg173 Arg174 Arg175
               Arg176 Arg177 Arg178 Arg179 Arg180 Arg181 Arg182 Arg183 Arg184 Arg185 Arg186 Arg187 Arg188 Arg189 Arg190 Arg191
               Arg192 Arg193 Arg194 Arg195 Arg196 Arg197 Arg198 Arg199 Arg200 Arg201 Arg202 Arg203 Arg204 Arg205 Arg206 Arg207
               Arg208 Arg209 Arg210 Arg211 Arg212 Arg213 Arg214 Arg215 Arg216 Arg217 Arg218 Arg219 Arg220 Arg221 Arg222 Arg223
               Arg224 Arg225 Arg226 Arg227 Arg228 Arg229 Arg230 Arg231 Arg232 Arg233 Arg234 Arg235 Arg236 Arg237 Arg238 Arg239
               Arg240 Arg241 Arg242 Arg243 Arg244 Arg245 Arg246 Arg247 Arg248 Arg249 Arg250 Arg251 Arg252 Arg253 Arg254
             )
    (setq a (+ a x))
  )
)

上面是nzl1116大侠发给我的试验程序,编译后确实第四个字节是0,而不是我上面说的2,原因出在哪里呢?
在cad的命令行上没法输入调用255个参数的函数ttt,我把源码改了一下,直接在程序后面加上
(ttt
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 )
程序源码直接加载可以运行,但编译后的fas出现了0xc0000005错误,证明我的结论是正确的,编译器确实生成了一个错误的文件。
把编译后的fas 14h后第四个字节改成2,运行结果正确。
感兴趣者可以自行试验。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册

x

评分

参与人数 1明经币 +1 收起 理由
tryhi + 1 牛逼啊!

查看全部评分

发表于 2020-7-20 17:06 | 显示全部楼层
baitang36 大师,帮忙看下我这个怎么转了FAS格式,命令失效  以下是源码
;过滤选择
(defun FILTER_by_DXF_code(ss DXF_code / ss i filter elist DXF_cons ssf n)
        (if ss
                (progn
                        (command "undo" "be")
                        (setq i 0)
                        (setq filter nil)
                        (repeat (sslength ss)
                                (setq elist(entget (ssname ss i)))
                                (if (assoc DXF_code elist)
                                        (if (=(type(cdr(assoc DXF_code elist))) 'STR)
                                                (setq DXF_cons  (cons DXF_code (ACET-STR-ESC-WILDCARDS1 (cdr(assoc DXF_code elist)))))       
                                                (setq DXF_cons  (assoc DXF_code elist))                               
                                        );;此处有修正
                                        (if(= DXF_code 62)
                                                (setq DXF_cons (cons  DXF_code 256))
                                        );;;只针对颜色为 bylayer 有用
                                );;end if
                                (setq filter (append filter (list DXF_cons)))
                                (setq i (1+ i))
                        );;end repeat
                        (setq filter (append '((-4 . "<or")) filter '((-4 . "or>"))));建立过滤表
                        (princ"\n请框选对象范围<按空格或右键全选>:")
                        (if (setq ssf (ssget filter))
                                (princ)
                                (setq ssf (ssget "x" filter))                               
                        )
                        (command "undo" "e")
                        (sssetfirst nil ssf)
                        (princ)
                )
                (princ"\n未选择,退出")
        )
        (princ)
);;end defun
;;62 按颜色过滤
(defun c:fgs() (princ "\n过滤选择---颜色")(FILTER_by_DXF_code (ssget) 62))
;;8  按图层过滤
(defun c:fgd() (princ "\n过滤选择---图层")(FILTER_by_DXF_code (ssget) 8 ))
;;0  按类型过滤
(defun c:fgf() (princ "\n过滤选择---类型")(FILTER_by_DXF_code (ssget) 0 ))
;;先选块,然后按块名过滤
(defun c:fgb() (princ "\n过滤选择---块名")(FILTER_by_DXF_code (ssget '((0 . "INSERT"))) 2))
;;先选填充,然后按填充样式过滤
(defun c:fgh() (princ "\n过滤选择---填充名")(FILTER_by_DXF_code (ssget '((0 . "HATCH"))) 2))
;;先选尺寸标注,然后按标注样式过滤
(defun c:fgr() (princ "\n过滤选择---标注样式")(FILTER_by_DXF_code (ssget '((0 . "*DIMENSION"))) 3))
;;先选文字,然后按字体样式过滤
(defun c:fgt() (princ "\n过滤选择---文字样式")(FILTER_by_DXF_code (ssget '((0 . "MTEXT,TEXT"))) 7))
;;先选文字,然后按文字内容过滤
(defun c:fgts() (princ "\n过滤选择---文字内容")(FILTER_by_DXF_code (ssget '((0 . "MTEXT,TEXT"))) 1))
;选填充
(DEFUN C:fgha()(princ "\n过滤选择---填充")(sssetfirst nil (ssget '((0 . "hatch"))))        (prin1))
;;只选文字
(DEFUN C:fgta()(princ "\n过滤选择---文字")(sssetfirst nil (ssget '((0 . "MTEXT,TEXT"))))        (prin1))
;;只选标注+箭头引线
(DEFUN C:fgre()(princ "\n过滤选择---标注+箭头引线")(sssetfirst nil (ssget '((0 . "*DIMENSION,LEADER"))))        (prin1))
;选文字+标注+箭头引线
(DEFUN C:fgtre()(princ "\n过滤选择---文字+标注+箭头引线")(sssetfirst nil (ssget '((0 . "MTEXT,TEXT,*DIMENSION,LEADER"))))        (prin1))
发表于 2020-3-19 16:48 | 显示全部楼层
谢谢楼主分享!!!
发表于 2020-3-19 17:54 | 显示全部楼层
为了不浪费币我没有下载
 楼主| 发表于 2020-3-19 17:57 | 显示全部楼层
jun353835273 发表于 2020-3-19 17:54
为了不浪费币我没有下载

将来学了asm或od再下载
发表于 2020-3-20 04:38 | 显示全部楼层
这帖发的毫无意义,漏洞百出,自己认为正确的东西,竟然没有用lsp验证。很简单的事情,弄256个无名变量的函数的lsp,编译下,看第四个字节是到底是0还是2,不就清楚了。
 楼主| 发表于 2020-3-20 08:40 | 显示全部楼层
本帖最后由 baitang36 于 2020-3-20 09:34 编辑
nzl1116 发表于 2020-3-20 04:38
这帖发的毫无意义,漏洞百出,自己认为正确的东西,竟然没有用lsp验证。很简单的事情,弄256个无名变量的函 ...

欢迎探讨。
我的意思是第一个和第四个字节的高位组合成的数值是被清除掉的无名变量的个数。这是我用od跟踪的结果,应该不会错。上一个函数使用过的无名变量,如果没被清除,它的值可以在下一个函数中使用。被清除掉了,内容就变成nil了。我把试验小程序发给你了,你看看?
你的255个变量加一个无名变量的程序,编译后确实是第四个字节是0,而不是我说的2,但我需要验证它运行时会不会出现0xc0000005错误。如果出错,说明编译器有问题,它编译出了一个不能运行的程序。如果不出错,说明我的研究还有不完善的地方,值得进一步研究。
发表于 2020-3-20 10:33 | 显示全部楼层
还真是,被acad编译器给忽悠了。
发表于 2020-3-20 15:05 | 显示全部楼层
baitang36 发表于 2020-3-20 09:24
(defun ttt (Arg000 Arg001 Arg002 Arg003 Arg004 Arg005 Arg006 Arg007 Arg008 Arg009 Arg010 Arg011 Arg0 ...

卧槽!牛逼啊,什么时候写个独立的编译器来给大伙用用,CAD那个编译器真的烂啊,不知道桌子这20年来到底更新了些什么东西
 楼主| 发表于 2020-3-20 18:06 | 显示全部楼层
tryhi 发表于 2020-3-20 15:05
卧槽!牛逼啊,什么时候写个独立的编译器来给大伙用用,CAD那个编译器真的烂啊,不知道桌子这20年来到底 ...

2018版的vlide和2008版没什么区别,稳定也好啊
您需要登录后才可以回帖 登录 | 注册

本版积分规则

小黑屋|手机版|CAD论坛|CAD教程|CAD下载|联系我们|关于明经|明经通道 ( 粤ICP备05003914号 )  
©2000-2023 明经通道 版权所有 本站代码,在未取得本站及作者授权的情况下,不得用于商业用途

GMT+8, 2024-5-7 00:39 , Processed in 0.309394 second(s), 29 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表