- 积分
- 813
- 实力分
- 点
- 金钱数
- 两
- 技术分
- 分
- 贡献分
- 分
|
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有帐号?注册会员
x
看到大家做补丁时好像还在使用一些过时的工具,比如我在用ultraedit搭建Patch开发环境里面说到的KeilC166,还有在输出注释方面的费尽排版。实在心有不忍,这里给大家介绍一下RizaPN创作的工具sfe,全名是siemens flash explorer,即“西门子Flash浏览器”,这给大家造成了假象,仿佛是类似于smelter一样的工具。实际上仅仅是sfe开始的功能,而sfe最强大的功能是他的开发能力,可以做到汇编C166生成vkp、bin等格式及行汇编,可以反汇编vkp,bin。而且甚至可以做到debugC166的程序。说起sfe的好处,那真是说也说不完!下面我就给大家介绍一下sfe的主要功能,并重点说一下patch所用到的、极大增强效率的功能。
我们先看一下Riza对它的介绍:
- sfe is my mini tools (around 50KB compressed exe file) to explore
- Siemens mobile phone flash file. Using this tools,
- we can do this following task :
- - search for free area inside the fullflash file (to put our patch),
- - binary copy, from any offset & source file to any offset & destination,
- - compare two files, and get the popular (patch) differences format,
- - find byte sequences with '?' (match with any digit) capability,
- - extract language data from fullflash file,
- - convert any text to language data,
- - extract menu structure and their entry-point,
- - C166 assembler and disassembler (yes! they are included!),
- - and even C166 debugger (yes! finally!)
复制代码
从sfe的开发历史来看,Riza从2003年的12月就开始了开发,那时我还在用Keil和ultraedit的集成环境。早期只是集成了Riza的一些工具,如fbytes、fmenu等,后来增加了汇编功能和语言包的处理。本质上说做Patch的都是些不安于现状、力图对环境有所改变的人,而Riza做得更为彻底!
我忘了自己从什么时候开始用的sfe,不过从那之后我就再也没有用过Keil(应该是从短消息计数开始,04-8)。并见证了sfe走向完美,起码对于C166的Patch来说,几乎是极致了!不啰嗦了,下面从简单功能开始分块说一下sfe的主要功能:
sfe是一个控制台工具,你可以通过在98下运行Command和在2K/XP下运行CMD进入控制台。sfe的命令格式如下:
- >sfe
- Usage : sfe <cmd> <parameters>
- cmd: [b]incopy binary copy
- [c]omp compare
- [d]isasm C166 disassembly
- [f]ind find bytes sequences or display file in hexa
- [i]nfo file info
- [l]ang language data information
- [m]enu explore menu structure
- [p]atch patching stuff
- [0]free search for free area
- [a]sm C166 assembler
- [r]un run C166 binary file
- Just enter sfe <cmd> to get more help for the specific <cmd>
- Add minus (-) sign before command to run it in verbose mode.
复制代码
在实际使用中,我发现恰好相反的是加-会抑制verbose模式。
而不加参数可以看命令的格式,如下:
- >sfe a
- Usage : sfe asm <asmfile[,name[,outfile]]> [<flag[,outsize[,baseAddr]]>] [<origFile>]
- name : patch name to be displayed (skip=all patches)
- outfile : output file
- flag : output format
- -> n : or without flag, normal
- -> d : complete (debugging purposes)
- -> p : patch format
- outsize : display output size perline
- baseAddr : baseAddr used in the patch format
- origFile : original fullflash file
复制代码
下面分别说一下sfe的功能
1、搜索Flash中的空闲区域。
这个没什么好说的了,如果要扩展功能的话,总要找一些地方放自己的代码,这个功能就是搜索Flash中全FF的部分,命令格式如下:
- Usage : sfe 0free <binfile> [numbytes]
- numbytes : number of byte 'FF' to be searched (default=0x300)
- Search for Free Area:
- =====================
- > sfe 0 ; get help
- > sfe 0 binfile.bin ; search free area (default = 0x300 bytes)
- > sfe 0 binfile.bin 1000 ; search for 0x1000 free bytes
复制代码 没有什么可说的,除了一个参数来指定最小的视为空闲Block的单位。
2、二进制格式拷贝。
Riza早期单独写过一个这样的工具,后来集成的sfe中来了,命令格式如下:
- Usage : sfe bincopy <srcfile[,pos[,size]]> <dsfile[,pos]>
- Binary Copy:
- ============
- > sfe b ; get help
- > sfe b src.bin dst.bin ; copy src.bin to dst.bin
- > sfe b src.bin,20 dst.bin ; copy src.bin, offset 0x20 to dst.bin
- > sfe b src.bin,20,100 dst.bin ; copy src.bin, offset 0x20 size 0x100 to dst.bin
- > sfe b src.bin,20,100 dst.bin,200 ; copy src.bin, offset 0x20 size 0x100 to dst.bin offset 0x200
复制代码 主要功能是把一个binary文件copy到另一个当中,可以指定偏移和拷贝数量。
3、文件比较。
类似于控制台下的FC工具,主要是用来比较二进制文件,有相当多的控制选项,命令格式如下:
- Usage : sfe find <srcfile[,pos[,size]]> <mark> [<dspbyte[,start]>]
- sfe find <srcfile[,pos[,size]]> <addr[,size]>
- mark(comma separated):
- blank anybyte
- 00-FF value
- 0?-F? low part match
- ?0-?F high part match
- example : E6,F?,,03
- dspbyte : number of byte to be displayed
- start : relatif start position to be displayed
- Compare Files:
- ==============
- > sfe c ; get help
- > sfe c src.bin dst.bin ; compare src.bin and dst.bin
- > sfe c src.bin,20 dst.bin ; compare src.bin from offset 0x20 with dst.bin
- > sfe c src.bin,20,100 dst.bin ; compare src.bin from offset 0x20 with dst.bin for 0x100 bytes
- > sfe c src.bin,20,100 dst.bin,300 ; compare src.bin from offset 0x20 with dst.bin from offset 0x300
- > sfe c src.bin,20 dst.bin a00000 ; compare and use a00000 as an output display base address
- > sfe c src.bin,20 dst.bin a00000,16 ; compare, use base address, and the size of each line is 16 bytes
- > sfe c src.bin,20 dst.bin a00000,16,all ; display all data from src.bin offset 0x20 and dst.bin (not only the differences)
复制代码 实际上,早期的Patch没有V_KLAY这样的工具,只能是直接在binary文件上修改,这个功能还是很有效的。
4、查找字节序列
这个功能早期是fbytes工具的功能,主要是在Flash中寻找具有字节特征的位置,比如某些指令,具有相同的操作码,但是不同位置的操作数不同,这是可以用??来进行模糊查找。对于在Flash中移植Patch时还是很有意义的,比如查找某个函数的调用情况,或者在不同机型中查找具有特定特征的指令。
- Usage : sfe find <srcfile[,pos[,size]]> <mark> [<dspbyte[,start]>]
- sfe find <srcfile[,pos[,size]]> <addr[,size]>
- mark(comma separated):
- blank anybyte
- 00-FF value
- 0?-F? low part match
- ?0-?F high part match
- example : E6,F?,,03
- dspbyte : number of byte to be displayed
- start : relatif start position to be displayed
- Find Byte Sequences:
- ====================
- > sfe f ; get help
- > sfe f src.bin e6,f?,,20,e6 ; search for 'E6 F? ?? 20 E6' sequences ? is match with any digit, blank is match with any byte
- > sfe f src.bin,200 e6,f?,,20,e6 ; same search but from offset 0x200
- > sfe f src.bin e6,f?,,20,e6 10 ; same search but displaying 10 bytes
- > sfe f src.bin e6,f?,,20,e6 10,4 ; same search, display 10 bytes starting from 4 previous bytes
- > sfe f src.bin 1234 ; display content of src.bin file (hexa format) starting from address, 80 bytes
- > sfe f src.bin 100:1000,8 ; same but display address 100:1000 (page:offset) for total 8 bytes.
复制代码
5、语言包的支持功能
sfe的语言包功能包括导出Flash中语言包的所有字串,显示Flash中的特定ID的字串,以及语言包中某个语言的字串等。其中支持文字到到语言包格式的转换。不过对中文的支持有点问题。
此外Riza在最新版本中添加了一些对语言包文件的支持,这个主要是为把特定程序作为语言包格式加载而作的准备,因为LG1的机器支持加载语言包和T9,其中语言包被加载到Flash的特定位置,利用这一特征,可以把bin格式的修改做成语言包的格式加载到Flash中。
- Usage : sfe l[c] <bin|lng-file> [<ID|-langno|'string|+hexcode> [<langno>]]
- ID : text id (hexa) to be displayed
- langno : language no to be displayed (all text)
- string : string to be converted
- hexcode : list of hexa code (space separated) to be decoded
- langno : language no to be used for convertion
- lc : check and correct LNG file
-
- Extract Language Data:
- ======================
- > sfe l ; get help
- > sfe l src.bin ; extract all data from the 1st language including the extended text data
- > sfe l src.bin 200 ; display string ID 200
- > sfe l src.bin 200 2 ; display string ID 200 from the 3rd language data (1st=0,2nd=1...)
- > sfe l src.bin -1 ; extract all data from the 2nd language
- > sfe l src.bin -all ; extract all existing language data
- > sfe l src.bin 'Testing ; convert 'Testing' text
- > sfe l src.bin 'Testing 1 ; convert 'Testing' text using langID 1
- > sfe l src.bin "+41 8C 91 56 4F" ; convert hexa data to text
- > sfe l scr.bin 200,"<95>Test" ; generate patch data to modify stringID 200 with text "<95>Test"
- > sfe l test.lng ; check LNG file test.lng for CRC and size data
- > sfe lc test.lng ; check and correct CRC and size data of test.lng
复制代码
6、Menu的支持功能
因为在西门子的手机中,某些菜单项有特定的格式,这个我在入门里面说过。而Riza是最早发现这个格式的人,并完成了fmenu程序,用来根据菜单文字来在Flash中查找菜单项结构,并可以确定此菜单的响应函数。
- Usage : sfe menu <binfile>
- Extract Menu:
- =============
- > sfe m ; get help
- > sfe m src.bin ; extract menu structure and entry-point
复制代码
7、Patch功能
这个功能是用来把VKP格式的Patch应用到二进制文件中去,和V_KLay的应用到文件功能类似,可知做到应用和撤销Patch。此外,在新版本的程序中,Riza为了支持Bin格式的Patch,需要一个从VKP格式的Patch生成二进制文件的功能,也在P功能里支持。
- Usage : sfe <patch|pd> <binfile> <patchfile> [<baseaddr>[,<patchID>[,undo]]]
- binfile : binary file to be patched
- baseaddr : the 1st 2 hexa digit for baseaddr
- patchID : patch name
- undo : undo the patch
- pd : binary file will always re-created
-
-
- Patching:
- =========
- > sfe p ; get help
- > sfe p sl45_44.bin patch.txt 44,BCI ; apply BCI patch for address 44zzzz from
- patch file patch.txt to file sl45_44.bin
- > sfe p sl45_44.bin p.txt 44,BCI,u ; undo BCI patch from patch file p.txt and
- bin file sl45_44.bin for address 44zzzz
- > sfe p binfile.bin p.txt 00,BCI ; create bin file binfile.bin from BCI patch
- file p.txt for address 00zzzz
复制代码
8、C166汇编
这个就是sfe最重要的功能,可以看到前面的功能都有类似的工具提供,而这个是sfe独一无二的,对于Patcher来说也是做得最好的。我在这里只是简单的介绍一下常用功能,在后面会详细的举例介绍汇编功能。
sfe的汇编功能可以说主要就是为patch而作的,所以对于patch来说,用起来非常的得心应手。sfe建立了一套自己的汇编规则,来支持patch。比如sfe支持VKP格式的直接输出,同时支持基址的设定。支持随意用org指令来设定Progrma Counter,来达到任意定位程序的功能,这一个是非常有意义的。此外,还支持行汇编功能。
- Usage : sfe asm <asmfile[,name[,outfile]]> [<flag[,outsize[,baseAddr]]>] [<origFile>]
- name : patch name to be displayed (skip=all patches)
- outfile : output file
- flag : output format
- -> n : or without flag, normal
- -> d : complete (debugging purposes)
- -> p : patch format
- outsize : display output size perline
- baseAddr : baseAddr used in the patch format
- origFile : original fullflash file
- Assembler:
- ==========
- > sfe a ; get help
- > sfe a src.asm ; compile src.asm
- > sfe a src.asm d ; compile src.asm, complete (debug) output
- > sfe a "mov r12, #1234h" ; inline assembler
- > sfe a "mov r2,r1 ; sub r2,#1" ; multiline inline assembler
- > sfe a src.asm,TST ; compile patch TST from src.asm
- > sfe a src.asm,TST p ; same function, patched display output
- > sfe a src.asm,TST p,10 ; same function, 0x10 bytes perline output
- > sfe a src.asm,TST p,10,a00000 ; same function, base address = 0xa00000
- > sfe a s.asm,TST p,10 org.bin ; include the original values from org.bin
- *) See Assembler Part to get more 'assembler' function detail
复制代码
9、C166反汇编功能
sfe的反汇编功能支持常规的从bin格式的文件中反汇编的功能,可以支持设定bin文件的开始汇编地址和长度,以及bin文件的基址。很有意义的功能就是sfe支持从vkp格式的文件中直接反汇编,这是一个非常方便的功能,在此之前,如果patch发布者没有发布源码的话,那其他人就只能把此vkp用IDC刷入IDA中进行反汇编了。此外,sfe为了支持显示任意图片的DrawImage功能,增加了解析BMP图片的功能,可以把BMP反汇编成内部的资源格式,下面的例子中会详细讲解一下。我没有试过这个功能对彩色图片的支持情况。
- Usage : sfe disasm <file[,pos[,size]]> [<baseaddr>,<flag>]
- file : binary, patch, or BMP file
- pos : start position to be disassembled
- size : number of byte to be read from the file
- baseaddr : base address to be used
- flag : p for patch format
- Disassembler:
- =============
- > sfe d ; get help
- > sfe d src.bin ; decompile src.bin
- > sfe d src.bin,200 ; decompile from offset 0x200
- > sfe d src.bin,200,100 ; same function, but only 0x100 bytes
- > sfe d src.bin,200,100 a00000 ; same function with base address for
- output A00000
- > sfe d src.bin,200,101 a00000 ; same function, but directly stop if
- 'RETS' command is founded before end
- > sfe d src.bin,200,101 a00000,p ; same function, asm ready output
- > sfe d t.txt,27e000,101 ; disassembler from patch file t.txt
- > sfe d image.bmp ; disasm bitmap (1 bit format), assembler output
- > sfe d image.bmp,8,8 10,10,img1 ; same function but for image at position 8,8
- with size 10x10, name it as img1
复制代码
10、Debug功能
sfe还提供了一个类似于dos下debug工具那样的调试环境,利用它可以进行一些非平台相关的调试工作,比如一个独立的算法,或者一个字符串处理的功能,都可以利用这个调试工具进行调试。sfe还可以加载一个文件作为RAM的内容。用这样的工具可以很容易的发现一些汇编时的笔误,比如将mov R6,#6写成mov R6, 6这种情况。我还从没用过这个功能。
- Usage : sfe run <file[,pos[,size]]> [baseAddr[,flag[,memFile]]]
- file : C166 binary or assembler file
- pos : file offset
- size : size of bytecode
- baseAddr: disassembler base address
- flag : run options
- memFile : memory configuration file
- Debugger:
- =========
- > sfe r ; get help
- > sfe r src.bin ; run bytecode from src.bin
- > sfe r src.asm ; run assembler command from src.asm
- > sfe r src.asm ,n ; same function, normal display output
- > sfe r src.bin,200 ; run from offset 0x200
- > sfe r src.bin,200,100 ; run 0x100 bytes from offset 0x200
- > sfe r src.bin b00000 ; run with base address B00000
- > sfe r src.bin ,,src.mem ; run with memory file src.mem
- > sfe r src.bin ,ri,src.mem ; run interractive debugger
- Interractive Debugger:
- ======================
- > h ; get help
- > g a00000 ; goto address a00000
- > g 37:3800 ; goto address 37:3800 (37*0x4000+3800 = DF800)
- > d ; dump memory (current address)
- > d a00000 ; dump memory address a00000
- > d a00000 200 ; dump memory address a00000, size 0x200
- > d r ; dump registers
- > a ; inline assembler
- > a c7d530 ; inline assembler at address c7d530
- > u ; display unassembler
- > u a00020 ; display unassembler address a00020
- > r ; run 1 command, current address
- > r 1 ; run 1 command (skip call), current address
- > r 0 ; run until return
- > r -c7d580 ; run until address c7d580
- > q ; quit
- *) All command without argument will change the current address
复制代码 介绍完了所有手册上的东西,就重点说一下自己平时经常用到的功能。
第一个就是反汇编VKP的功能,不过这个要注意,VKP的格式要符合0xNNNN: XXXX YYYY这样的,如果中间的空格多于一个的话,就会反汇编的面貌全非。此外,sfe不能正确地处理vkp中的数据部分,只能自己来手工处理一下,如下面的例子:
- 0x35E748: F0C8F0D9 DAF6002F
- 0x562F00: FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF F0C8F0D9E6FE2000DAF60403D7400D00
- 0x562F10: FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF F2F4E6255C14D740D803D4442E2FF0C8
- 0x562F20: FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF F0D9F0E4DAF60403F0C8F0D9DB000A54
- 0x562F30: FFFFFFFFFFFFFFFFFFFFFFFF 015403540454065408540954
复制代码 这个是修改待机日期增加星期的一个patch,那么我们把它存到文件patch.txt里,然后用下面的命令来反汇编它。不过因为sfe的限制,我们只能指定一个pos:
- >sfe d patch.txt,562F00,101 A00000,p
- ;Siemens Flash Explorer v2.51c (c)Dec.03 by RizaPN <rizapn@yahoo.com>
- ;File patch.txt (pos=0x0,sz=0x141,rd=0x141) buffered
- ;Disassembly: offset=0x0, size=0x141, baseAddr=0xA00000
- org 0F62F00h
- mov r12, r8
- mov r13, r9
- mov r14, #20h
- calls 0F6h, 304h
- extp #0Dh, #1
- mov r4, 25E6h
- shl r4, #1
- extp #3D8h, #1
- mov r4, [r4+#2F2Eh]
- mov r12, r8
- mov r13, r9
- mov r14, r4
- calls 0F6h, 304h
- mov r12, r8
- mov r13, r9
- rets
- bfldl 0FEA8h, #1, #54h
- addb 0FEA8h, 5404h
- add 0FEA8h, #5408h
- addb rh2, #4
- end
复制代码 知里面562F00是开始地址,101表示到ret结束,当然也可给出具体的size或者一个大的size来汇编从562F00开始的部分。A00000表示基址,p表示汇编格式,如果不加p就是如下输出:
- >sfe d patch.txt,562F00,1000 A00000,
- ;Siemens Flash Explorer v2.51c (c)Dec.03 by RizaPN <rizapn@yahoo.com>
- ;File patch.txt (pos=0x0,sz=0x141,rd=0x141) buffered
- ;Disassembly: offset=0x0, size=0x141, baseAddr=0xA00000
- 562F00: F0 C8 : mov r12, r8
- 562F02: F0 D9 : mov r13, r9
- 562F04: E6 FE 20 00 : mov r14, #20h
- 562F08: DA F6 04 03 : calls 0F6h, loc_F60304
- 562F0C: D7 40 0D 00 : extp #0Dh, #1
- 562F10: F2 F4 E6 25 : mov r4, 365E6h ; (000D:25E6)
- 562F14: 5C 14 : shl r4, #1
- 562F16: D7 40 D8 03 : extp #3D8h, #1
- 562F1A: D4 44 2E 2F : mov r4, [r4+#2F2Eh]
- 562F1E: F0 C8 : mov r12, r8
- 562F20: F0 D9 : mov r13, r9
- 562F22: F0 E4 : mov r14, r4
- 562F24: DA F6 04 03 : calls 0F6h, loc_F60304
- 562F28: F0 C8 : mov r12, r8
- 562F2A: F0 D9 : mov r13, r9
- 562F2C: DB 00 : rets
- ;------------------------------------------------------------
- 562F2E: 0A 54 01 54 : bfldl mem_FEA8, #1, #54h
- 562F32: 03 54 04 54 : addb mem_FEA8, 5404h
- 562F36: 06 54 08 54 : add mem_FEA8, #5408h
- 562F3A: 09 54 : addb rh2, #4
复制代码 可以看到,sfe不能正确地识别数据部分,就是从562F2E开始的中文星期定义。
除此以外,sfe的反汇编指令里面还包括了处理单色bmp图片的功能,在siemens的黑白机中,图片一般是如下格式:
- struct bmpheader{
- byte width;
- byte height
- word flag;
- word offset;
- word page;
- }
复制代码 其中offset和page指向具体的图片内容。大家都使用过DrawPredefImage的函数,传入一个图片ID来显示预置图片,实际上,还可以给定一个bmpheader来显示任意图片,在6688中,这个函数是DrawImage->0D111CAh。它接受的参数是一个bmpheader的结构体和显示的区域,此外就是和DrawPredefImage一样的显示位置。我们看一下下面的Patch:
- ;-------------------------------------------
- ;#name ICI. IME Change Icon
- ;-------------------------------------------
- ;[0F63400h - 0F634FFh]
- '6688V55 -D- 05.03.04 - coollang[SPGC] - 另一个输入法图标替换[563400h - 5634FFh]
- '【Flash修改】另一个输入法图标替换
- '适用:6688V55
- '作者:coollang[SPGC]
- '版本:V1.0
- '说明:这个和sOLO的功能是一样的,不过用了另一个显示图片的函数,图片数据在补丁中
- ' 不会有图片冲突,此外我在切换输入法的地方调用了一下SetCurrentIME,更新了
- ' 数据,所以在切换输入时也会正常显示。
- org 0E4B290h
- calls IME_CorrectImage
- org 0E3A178h
- calls IME_SetCurrentIME
-
- org 0F63400h
- IME_CorrectImage:
- calls 0D9E6F2h
- cmpb rl4, #06h
- jmpr cc_Z, IME_CorrectImage_06
- IME_DisableBiHua:
- cmpb rl4, #08h
- jmpr cc_Z, IME_CorrectImage_08
- calls DrawImageByIndex
- rets
- IME_CorrectImage_06:
- mov r4, #pof(hdr_IME)
- mov r5, #pag(hdr_IME)
- jmpr cc_UC, IME_CorrectImage_Draw
- IME_CorrectImage_08:
- mov r4, #pof(hdr_IME2)
- mov r5, #pag(hdr_IME2)
- IME_CorrectImage_Draw:
- mov [-r0], r5
- mov [-r0], r4
- mov r14, #74
- mov r15, #8
- calls drawImage
- add r0, #4
- rets
-
- IME_SetCurrentIME:
- mov r12, r8
- mov r13, r9
- calls 0E3B852h ;GetContextIME
- mov r12, r4
- calls 0D9E6E6h ;SetCurrentIME
- mov r12, r8
- mov r13, r9
- rets
- '图片数据,用sfe 2.51生成.
- hdr_IME:
- db 74,8,1,0
- dw pof(bmp_IME),pag(bmp_IME)
- bmp_IME:
- db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
- db 0x01,0x00,0x78,0x03,0x00,0x00,0x03,0x00,0x00,0x00
- db 0x03,0x00,0x40,0x04,0x80,0x54,0x04,0x80,0x28,0x00
- db 0x01,0x00,0x70,0x04,0x80,0x38,0x04,0x80,0x7C,0x00
- db 0x01,0x00,0x08,0x03,0x80,0x10,0x04,0x80,0x28,0x00
- db 0x01,0x00,0x08,0x00,0x80,0x38,0x04,0x80,0x7C,0x00
- db 0x01,0x00,0x70,0x07,0x00,0x54,0x03,0x00,0x28,0x00
- db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-
- hdr_IME2:
- db 74,8,1,0
- dw pof(bmp_IME2),pag(bmp_IME2)
- bmp_IME2:
- db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
- db 0x1F,0x00,0xE0,0x03,0x00,0x00,0x03,0x00,0x00,0x00
- db 0x01,0x01,0x10,0x04,0x80,0x54,0x04,0x80,0x28,0x00
- db 0x02,0x00,0xE0,0x04,0x80,0x38,0x04,0x80,0x7C,0x00
- db 0x04,0x01,0x10,0x03,0x80,0x10,0x04,0x80,0x28,0x00
- db 0x08,0x01,0x10,0x00,0x80,0x38,0x04,0x80,0x7C,0x00
- db 0x08,0x00,0xE0,0x07,0x00,0x54,0x03,0x00,0x28,0x00
- db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
- ';如果不想改变笔画输入法的图片,取消下面的注释
- org IME_DisableBiHua
- nop
- nop
- nop
复制代码 这是另一个输入法图标的源码,从这里面我们可以看到sfe汇编的很多先进用法。其中hdr_IME和hdr_IME2是用sfe生成的。命令如下:
- >sfe -d bh.bmp,0,0 74,8,IME
- ;bh.bmp 74x8 pixels (0,0 74x8)
- hdr_IME:
- db 74,8,1,0
- dw pof(bmp_IME),pag(bmp_IME)
- bmp_IME:
- db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
- db 0x1F,0x00,0xE0,0x03,0x00,0x00,0x03,0x00,0x00,0x00
- db 0x01,0x01,0x10,0x04,0x80,0x54,0x04,0x80,0x28,0x00
- db 0x02,0x00,0xE0,0x04,0x80,0x38,0x04,0x80,0x7C,0x00
- db 0x04,0x01,0x10,0x03,0x80,0x10,0x04,0x80,0x28,0x00
- db 0x08,0x01,0x10,0x00,0x80,0x38,0x04,0x80,0x7C,0x00
- db 0x08,0x00,0xE0,0x07,0x00,0x54,0x03,0x00,0x28,0x00
- db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
复制代码 这里面,你可以指定图片中开始的位置和大小,或者是不指定,如下面的格式:
下面我们具体说一下sfe的编译功能,这个我感觉是sfe最强大的功能。下面是sfe支持的语法!
- Specific Assembler Mnemonic:
- ============================
- *) All standard C166 mnemonic is implemented.
- *) Character ; is used to put the remark (anywhere in the line)
- *) "Non-standard" mnemonic implemented are :
- #include filename ; include commands from filename (definitions)
- #define var value ; set variable var = value
- var equ value ; set var = value
- db 'X',36h ; define byte(s)
- dw 1234h,0,'AB' ; define word(s)
- org ; set the current address
- base ; set base Address (output address in the patch format
- will be (currentAddress-baseAddress)
- end ; end of processed file
- ;#name XXX.string ; patch name definition (XXX)
- ' ; printed as remark in the patch output
- '' ; printed as <enter> in the patch output
- '; ; printed as remark, and all the following code is remarked
- until '' is found
- ;' ; remark will be printed also in the patch output
- + - * / % ; add, sub, mul, div, and mod operation
- >> > < << ; shr and shl operation
- & && | || ^ ^^ ; and, or, xor operation
- val1:val2 ; page operation (val = val1 * 0x4000 + val2)
- page(value),
- pag(value),
- p(value) ; page value (= value / 0x4000)
- pof(value),
- q(value) ; offset of page value (= value mod 0x4000)
- segment(value),
- seg(value),
- s(value) ; segment value (= value div 0xFFFF)
- offset(value),
- ofs(value),
- sof(value),
- o(value) ; offset of segment value (= value mod 0xFFFF)
复制代码
其中比较特殊的是:
1、org。org用来指定程序计数器的地址,也就是PC的地址,相当于指定汇编开始的地址。
2、base。base可以指定基址,这个主要用来辅助sfe转换内部地址到文件偏移用的。
3、;#name XXX.string。patch名定义,sfe支持在一个文件内定义多个patch的机制,就是用name来指定patch名,不过我的建议是,尽量不要把太多的patch放在一个文件里,那样的编译速度是非常慢的,几乎难以忍受,我的感觉是sfe编译所有的patch,然后输出特定的patch。
4、sfe的注释功能,这是sfe最强大的功能了,通过增加注释的格式,来控制生成的vkp的各种说明文字,使注释不仅仅是开发时的说明文字,而是直接输出到终极的patch中。具体的格式有:
a、; 普通注释
b、' 注释会被输出到生成的vkp中。
c、'' 在输出中增加一个换行。
d、'; 以下所有的代码会作为注释输出,直到遇见一个 ''。这个用来提供某些选项时非常有效,比如常见的“要想xxx取消一下三行的注释”。
e、;' 一般是在vkp的补丁内容后面添加注释,和'不同的是不换行。
5、page,segment和offset族。这些主要是因为C166是段页式寻址的,用来指定线性地址的段和页以及段内和页内偏移。但是我推荐你使用标准的pof,pag,seg,sof。因为这样把程序移植到别的编译器上比较方便。 |
|