coollang 发表于 2005-8-15 00:00:00

[Patch工具]sfe使用详解

看到大家做补丁时好像还在使用一些过时的工具,比如我在用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: incopybinary copy
   omp   compare
   isasm   C166 disassembly
   ind   find bytes sequences or display file in hexa
   nfo   file info
   ang   language data information
   enu   explore menu structure
   atch    patching stuff
   free    search for free area
   sm      C166 assembler
   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 : 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):
   blankanybyte
   00-FFvalue
   0?-F?low part match
   ?0-?Fhigh 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):
   blankanybyte
   00-FFvalue
   0?-F?low part match
   ?0-?Fhigh 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 startingfrom 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 <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]]> ]]
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,
      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,
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
;-------------------------------------------
;
'6688V55 -D- 05.03.04 - coollang - 另一个输入法图标替换
'【Flash修改】另一个输入法图标替换
'适用:6688V55
'作者:coollang
'版本: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 -d bh.bmp ,,IME

下面我们具体说一下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。因为这样把程序移植到别的编译器上比较方便。

RainMoon 发表于 2005-8-15 00:01:00

哈,来得早不如来得巧,第一个来听狼大讲课了。

regspy 发表于 2005-8-15 00:02:00

最新版本在FTP里下载吗?

coollang 发表于 2005-8-15 00:03:00

sfe只适用于C166处理器的机型,即E-GOLD的内核的,包括X65以下的机器和A65,不适用于X65。
最新版本站FTP的SPGC/C166/Tools里有下载!

云卷.云舒 发表于 2005-8-15 00:04:00

学习.~~~~~~~~

regspy 发表于 2005-8-15 00:05:00

谢谢 狼大
唉,要是有个65版的就好 了

Xinshou 发表于 2005-8-15 00:06:00

真是适时的教材. 谢谢!

下午四点半 发表于 2005-8-15 00:07:00


知道好东西
可是看不懂

qtazure 发表于 2005-8-15 00:08:00

来晚了来晚了
听狼大上课

comerose 发表于 2005-8-15 00:09:00

我也来晚,学习学习!

beyond 发表于 2005-8-15 00:10:00

好东西,先顶再学习。

Xinshou 发表于 2005-8-15 00:11:00

转换补丁成bin文件的方法:

在Dos提示符键入 sfe p patch.bin patch.txt 5A

注意先将补丁里的原始数据(如FFFFFFFFFFFFFFFF)全部删除,地址后只跟新数据。

fhq1999 发表于 2005-8-15 00:12:00

呵呵,没有前排就占第一页学习吧

rosey_bear 发表于 2005-8-15 00:13:00

啊,看得头都大了, 看来大虾不是盖的哦!!!

wwh944116 发表于 2005-8-15 00:14:00

自从上次深圳机友会后,KONCA指点了我,就一直用SFE来做补丁的,不过只用了A 功能.哈,想不到这么多功能啊.
另外不知是否版本的问题.我完全照着狼大的方法.使用D功能(反汇编),这个功能我可以用于FULLFLASH.比如:sfe d mc60.bin,551500,10 p 这样是可以反汇编出551500后的一些代码.但是如果我试图反汇编一个VKP的补丁时出现的却是乱七八糟的东西.为什么?比如上面狼大的例子,那个增加星期的补丁.一切照做,试了很多次,出来的东西根本看不懂.到底是什么问题? 如果是版本的问题的话,由于我上不了FTP,哪位好心人传一个SFE给我好吗?
我的邮箱:   wwh944116@163.com
谢谢!

Xinshou 发表于 2005-8-15 00:15:00

可能是补丁格式问题,试试将原始数据(如FFFFFFFFFFFFFFFF)全部删除,或别的。

coollang 发表于 2005-8-15 00:16:00

Originally posted by wwh944116 at 2005-6-6 14:15
自从上次深圳机友会后,KONCA指点了我,就一直用SFE来做补丁的,不过只用了A 功能.哈,想不到这么多功能啊.
另外不知是否版本的问题.我完全照着狼大的方法.使用D功能(反汇编),这个功能我可以用于FULLFLASH.比如:sfe...
反汇编vkp时格式要确定,只能有一个空格,不过我觉得你的是因为版本不够的原因。我上传一个吧。

wwh944116 发表于 2005-8-15 00:17:00

前几次老是发不上去.
问题解决了.的确是版本的问题.
另请教一个问题.这是一段关于分离秒的.
extp #7, #1
mov r4,33deh;取得通话时长
                ;分离出秒.
mov r12,#3ch   ;60
mov Md,r4
atomic #2******这一句什么意思?
divu r12
nop

coollang 发表于 2005-8-15 00:18:00

原帖由 wwh944116 于 2005-6-7 08:27 发表
前几次老是发不上去.
问题解决了.的确是版本的问题.
另请教一个问题.这是一段关于分离秒的.
extp #7, #1
mov r4,33deh;取得通话时长
                ;分离出秒.
mov r12,#3ch   ;60
mov Md,r4
atomic...
atomic 是一个原子指令操作,类似于x86的locked操作,表明下面的几条指令不会被中断打断,具体的可以看处理器手册。这是手册上对指令的描绘:
Begin ATOMIC Sequence ATOMIC
Syntax ATOMIC op1
Operation (count) &not; (op1)
Disable interrupts and Class A traps
DO WHILE ((count) &sup1; 0 AND Class_B_trap_condition &sup1; TRUE)
Next Instruction
(count) &not; (count) - 1
END WHILE
(count) = 0
Enable interrupts and traps
Description Causes standard and PEC interrupts and class A hardware traps to be
disabled for a specified number of instructions. The ATOMIC instruction
becomes immediately active such that no additional NOPs are required.
Depending on the value of op1, the period of validity of the ATOMIC
sequence extends over the sequence of the next 1 to 4 instructions being
executed after the ATOMIC instruction. All instructions requiring multiple
cycles or hold states to be executed are regarded as one instruction in this
sense. Any instruction type can be used with the ATOMIC instruction.
Note The ATOMIC instruction must be used carefully (see introductory note).
The ATOMIC instruction is not available in the SAB 8XC166(W) devices.

Simple2000 发表于 2005-8-15 00:19:00

顶一下
先留个记号,以后慢慢看
页: [1] 2
查看完整版本: [Patch工具]sfe使用详解