首页
社区
课程
招聘
[求助]foxpro下调用bin文件如果转到VFP
发表于: 2009-8-10 14:06 10793

[求助]foxpro下调用bin文件如果转到VFP

2009-8-10 14:06
10793
foxpro下调用bin文件如果转到VFP,只有几百个字节,哪个老兄分析一下完成了什么功能
总共才200多个字节的汇编小程序,后缀是bin,哪位精于汇编和通讯的兄弟帮助看一上它到底完成了什么功能,如果完成这个功能,先谢了

两个bin文件在附件里

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

上传的附件:
收藏
免费 0
支持
分享
最新回复 (20)
雪    币: 2087
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
古董级的东西还有人在用!
2009-8-10 14:09
0
雪    币: 1889
活跃值: (193)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
3
是的,我的一个朋友要求必须做的,我都快哭了,asm和传感器的通讯我一点都不懂
2009-8-10 14:24
0
雪    币: 2087
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
分析一下通信协议,应该是串口吧?RS232
2009-8-10 14:58
0
雪    币: 1889
活跃值: (193)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
5
这个设备都不在我身边,我连见都没见过
2009-8-10 18:30
0
雪    币:
能力值: (RANK: )
在线值:
发帖
回帖
粉丝
6
用0x2E8(通常是Com4)与某设备进行通讯, 应该只是端口I/O部分, 具体的数据分析还是在VFP程序里的.
如果没有设备, 还不如直接反编译VFP程序, 找出它的调用参数和数据处理算法, 看看能否跳过或替代.
2009-8-10 23:18
0
雪    币: 1889
活跃值: (193)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
7
PUBLIC s_fr, s_f1r, s_br, s_b1r, s_xr, s_x1r, s_pr, s_p1r, s_gr,  ;
       s_g1r, s_sr, s_s1r, s_fl, s_f1l, s_bl, s_b1l, s_xl, s_x1l,  ;
       s_pl, s_p1l, s_gl, s_g1l, s_sl, s_s1l, xzz, row1, coiumn1,  ;
       size_h1, size_v1, pict1, row2, coiumn2, size_h2, size_v2,  ;
       pict2
xzz = 1
s_fr = ""
s_f1r = ""
s_br = ""
s_b1r = ""
s_xr = ""
s_x1r = ""
s_pr = ""
s_p1r = ""
s_gr = ""
s_g1r = ""
s_sr = ""
s_s1r = ""
s_fl = ""
s_f1l = ""
s_bl = ""
s_b1l = ""
s_xl = ""
s_x1l = ""
s_pl = ""
s_p1l = ""
s_gl = ""
s_g1l = ""
s_sl = ""
s_s1l = ""
PUBLIC gcom, gcomuse, gcomt, gcomn
gcom = 1
gcomuse = 0
gcomt = 0.1
gcomn = 1
IF FILE("GCOM.MEM")
RESTORE FROM GCOM ADDITIVE
ENDIF
load z0
load zy
IF gcomuse = 1
WAIT WINDOW NOWAIT "请连接测试仪..."
CALL zo WITH CHR(gcom - 1)
WAIT CLEAR
ENDIF

此后就对上面初始化的这些变量开始正式调用,也就是说,这个zo.bin 被load后再call一下就完成了上面一组内存变量的赋值。
2009-8-11 15:35
0
雪    币:
能力值: (RANK: )
在线值:
发帖
回帖
粉丝
8
仔细看了一下, ZO里所做的事只是测试那个"测试仪"是否存在(接口参数为1200, 8-N-1), 入口参数为对应所连接的Com口.
具体的流程是
1. 按1200, 8-N-1设置Com口
2. 发送10个字节 "EE 30 36 30 39  32 37 39 31 EE"
3. 等待并检查Com口返回的值是否是"BB 31 30 31 34 31 34 39 31 BB"
其中EE和BB应该是数据开始的标志, 真正的值是"06092791"和"10141491", 大概是这个"测试仪"的序列号之类的.
ZY则负责从COM口中读入一个7 bits的数据, 入口参数为对应所连接的Com口, 出口参数(与入口参数共用)为读入的数据(al & 0x7F), (注意: ZY假设ZO已经将COM口设置好了)
这样看来, 调用ZO这部分可以忽略(直接喀嚓), 关键是调用ZY那些地方, 看看读出的数据用来干什么.
2009-8-11 22:09
0
雪    币: 1889
活跃值: (193)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
9
多谢楼上的这个兄弟,以下附上zy调用部分的源码,看能否指教一二,小狐先谢过了

PARAMETER wmess
PRIVATE val, val0, val1, try
field1 = VARREAD()
SHOW GET (field1) COLOR ,W+/B,
val0 = zyget()
val0 = IIF(val0 > 10, 0, val0)
WAIT WINDOW NOWAIT wmess + '初值' +  ;
     ALLTRIM(STR(val0))
SET BELL TO 2048, 1
? CHR(7)
SET BELL TO 512, 2
SHOW GET (field1) COLOR ,W+/B,
val1 = val0
val = val1
IF val0 > 110
     ?? CHR(7)
     WAIT WINDOW '接口无效!'
     gcomuse = 0
     RETURN
ENDIF
try = 1
tryn = 0
DO WHILE (val1<val0+5 .OR. val1> ;
   val .OR. tryn<2)
     val1 = zyget() * xzz
     IF val1 > 80
          WAIT WINDOW NOWAIT  ;
               '退格'
          SHOW GET (field1) COLOR , ;
               RGB(0,0,255,,,),
          ?? CHR(7)
          RETURN -1
     ENDIF
     IF val1 > val
          val = val1
          tryn = 0
     ELSE
          tryn = tryn + 1
     ENDIF
     WAIT WINDOW NOWAIT wmess +  ;
          '初值' +  ;
          ALLTRIM(STR(val0)) +  ;
          '测量值' +  ;
          ALLTRIM(STR(val1))
     try = try + 1
     SHOW GET (field1) COLOR ,W+/ ;
          B,
     @ row1,coiumn1 SAY (LOCFILE("人体图库\&pict1","BMP|ICO",;
"Where is &pict1?")) BITMAP  SIZE size_h1,size_v1  STYLE "T"
     @ row2, coiumn2 TO size_h2,  ;
       size_v2 STYLE '99' PATTERN  ;
       1 PEN 1, 8 COLOR RGB(,,, ;
       255,0,0)
     = INKEY(0.5 , 'H')
     @ row1,coiumn1 SAY (LOCFILE("人体图库\&pict2","BMP|ICO",;
"Where is &pict2?")) BITMAP  SIZE size_h1,size_v1  STYLE "T"
     @ row2, coiumn2 TO size_h2,  ;
       size_v2 STYLE '99' PATTERN  ;
       1 PEN 1, 8 COLOR RGB(,,,0, ;
       255,0)
     SHOW GET (field1) COLOR ,W+/ ;
          B,
     IF try > 20
          bzyin = 'Y'
          ?? CHR(7)
          WAIT TO bzyin WINDOW  ;
               '是否继续测量(Y/N)?'
          IF bzyin $ 'Nn'
               SHOW GET (field1)  ;
                    COLOR ,RGB(0, ;
                    0,255,,,),
               gcomuse = 0
               RETURN TO main
          ELSE
               IF bzyin $ 'Yy'
                    try = 0
               ELSE
                    try = 30
               ENDIF
          ENDIF
     ENDIF
ENDDO
REPLACE (field1) WITH val
SHOW GET (field1)
? CHR(7)
try = 1
DO WHILE (val1<val0-4 .OR. val1> ;
   val0+4) .AND. try<8
     SHOW GET (field1) COLOR ,W+/ ;
          B,
     WAIT WINDOW NOWAIT '复位...'
     val1 = zyget()
     try = try + 1
ENDDO
WAIT CLEAR
SHOW GET (field1) COLOR ,RGB(0,0, ;
     255,,,),
xzz = 1
RETURN 1
*
FUNCTION zyget
PRIVATE i, m, m0, m1, m2
i = 0
m0 = CHR(gcom - 1)
m1 = 0
m2 = 0
DO WHILE i<gcomn
     m = m0
     CALL zy WITH m
     m1 = ASC(m)
     IF m1 - m2 <= 2 .AND. m1 -  ;
        m2 >= -2
          i = i + 1
          IF m1 > m2
               m2 = m1
          ENDIF
     ELSE
          m2 = m1
          i = 0
     ENDIF
     = INKEY(gcomt)
ENDDO
RETURN m2
*
2009-8-12 08:17
0
雪    币:
能力值: (RANK: )
在线值:
发帖
回帖
粉丝
10
不知道你是否处理过代码, 单就贴上来的这段代码来看, 从"测量仪"中读取的数据只是用来做为程序流程的控制参数, 同时不断的用类似泡泡的机制将该值显示出来.
你不妨问清楚这个"测量仪"到底是用来"测"什么的吧, 从代码内容以及1200这个波特率来看, 象是医院的多功能自动监控仪, 这个程序的作用是自动收集数据并记录到数据库中备案.
2009-8-12 23:25
0
雪    币:
能力值: (RANK: )
在线值:
发帖
回帖
粉丝
11
突然看到你的要求只是把程序由Foxpro迁移到VFP, 那工作就简单了.
这两个模块的功能我在8楼已经说得很明白了, VFP支持直接调用外部C写的库, 你直接写一个操作 COM 口的库替换它(包括调用方式)就可以了.
2009-8-12 23:37
0
雪    币: 1889
活跃值: (193)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
12
arab兄弟,请和小狐取得联系好吗,小狐希望得到你的指点
小狐QQ:86074731
2009-8-13 14:49
0
雪    币:
能力值: (RANK: )
在线值:
发帖
回帖
粉丝
13
有事直说.
让我帮忙干活写东西的话就不必说了, 没时间.
有偿也不行.
2009-8-13 23:34
0
雪    币: 1889
活跃值: (193)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
14
VFP中在gird中怎么才能一敲回车就让光标移到下一行上

我偶然找这个问题,居然发现在国内很我相关的编程论坛上有很多笨人和N条语句来实现这个功能
于是就翻了一下原来的代码,现在贴出来,一句搞定,希望以上的关键词能给pediy增加点人气.

把以下语句直接放到form的loa事件里,这时你在回车时实现的就是下箭头的功能

ON KEY LABEL enter keyboard '{dnarrow}'
2009-8-16 11:57
0
雪    币: 1889
活跃值: (193)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
15
关于zy.bin
===============================
我用w32asm反汇编合适吗?(原程序为16位汇编)
如果合适,请懂行的兄弟把如下代码给我注释一下,如果不行那就只能用debug了吧

如果用debug,比如我把zy.bin放到d:\,当我输入cmd并输入d:后转到在盘
我再输入debug zy.bin进入debugl界面
然后发u cs:000 50 是可以看到所有16位汇编的代码的,关键是我用debug的什么命令给它的反汇编结果重定向到一个文本文件里,请高手指教。

:00000000 EB01                    jmp 00000003
:00000002 90                      nop
:00000003 06                      push es
:00000004 52                      push edx
:00000005 51                      push ecx
:00000006 50                      push eax
:00000007 1E                      push ds
:00000008 53                      push ebx
:00000009 53                      push ebx
:0000000A B910018A07              mov ecx, 078A0110
:0000000F C60700                  mov byte ptr [edi], 00
:00000012 3C00                    cmp al, 00
:00000014 7411                    je 00000027
:00000016 B910003C01              mov ecx, 013C0010
:0000001B 740A                    je 00000027
:0000001D B900013C02              mov ecx, 023C0100
:00000022 7403                    je 00000027
:00000024 B90000BAED              mov ecx, EDBA0000
:00000029 0203                    add al, byte ptr [ebx]
:0000002B D1EC                    shr esp, 1
:0000002D 8AE0                    mov ah, al
:0000002F F6C401                  test ah, 01
:00000032 740A                    je 0000003E
:00000034 BAE80203D1              mov edx, D10302E8
:00000039 EC                      in al, dx
:0000003A 247F                    and al, 7F
:0000003C 8807                    mov byte ptr [edi], al
:0000003E 5B                      pop ebx
:0000003F 5B                      pop ebx
:00000040 1F                      pop ds
:00000041 58                      pop eax
:00000042 59                      pop ecx
:00000043 5A                      pop edx
:00000044 07                      pop es
:00000045 CB                      retf
2009-8-18 09:55
0
雪    币: 1889
活跃值: (193)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
16
arab兄弟,能过这两个小程序的分析,可以肯定是用的哪个com口吗?

另外com口读过来的数值一定要经过:"出口参数(与入口参数共用)为读入的数据(al & 0x7F), "这个步骤吗?

我现在想调用mscomm32.ocx读这个com口,读出来还要有你说的那个动作吗?

在线等...
2009-8-18 10:47
0
雪    币: 1889
活跃值: (193)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
17
最后一次准确的用w32adm反汇编出的两个程序的16位汇编源码:

zy的汇编源码:
:0001.0003 06                     push es
:0001.0004 52                     push dx
:0001.0005 51                     push cx
:0001.0006 50                     push ax
:0001.0007 1E                     push ds
:0001.0008 53                     push bx
:0001.0009 53                     push bx
:0001.000A B91001                 mov cx, 0110
:0001.000D 8A07                   mov al , [bx]
:0001.000F C60700                 mov byte ptr [bx], 00
:0001.0012 3C00                   cmp al, 00
:0001.0014 7411                   je 0027
:0001.0016 B91000                 mov cx, 0010
:0001.0019 3C01                   cmp al, 01
:0001.001B 740A                   je 0027
:0001.001D B90001                 mov cx, 0100
:0001.0020 3C02                   cmp al, 02
:0001.0022 7403                   je 0027
:0001.0024 B90000                 mov cx, 0000

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:0001.0014(C), :0001.001B(C), :0001.0022(C)
|
:0001.0027 BAED02                 mov dx, 02ED
:0001.002A 03D1                   add dx, cx
:0001.002C EC                     in al, dx
:0001.002D 8AE0                   mov ah, al
:0001.002F F6C401                 test ah, 01
:0001.0032 740A                   je 003E
:0001.0034 BAE802                 mov dx, 02E8
:0001.0037 03D1                   add dx, cx
:0001.0039 EC                     in al, dx
:0001.003A 247F                   and al, 7F
:0001.003C 8807                   mov [bx], al

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0001.0032(C)
|
:0001.003E 5B                     pop bx
:0001.003F 5B                     pop bx
:0001.0040 1F                     pop ds
:0001.0041 58                     pop ax
:0001.0042 59                     pop cx
:0001.0043 5A                     pop dx
:0001.0044 07                     pop es
:0001.0045 CB                     retf

zo的汇编源码

:0001.0000 EB13                   jmp 0015

:0001.0002 90                     nop
:0001.0003 EE                     out dx, al
:0001.0004 30363039               xor [3930], dh
:0001.0008 3237                   xor dh, [bx]
:0001.000A 3931                   cmp [bx+di], si
:0001.000C EE                     out dx, al
:0001.000D 3130                   xor [bx+si], si
:0001.000F 3134                   xor [si], si
:0001.0011 3134                   xor [si], si
:0001.0013 3931                   cmp [bx+di], si

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0001.0000(U)
|
:0001.0015 06                     push es
:0001.0016 52                     push dx
:0001.0017 51                     push cx
:0001.0018 50                     push ax
:0001.0019 1E                     push ds
:0001.001A 53                     push bx
:0001.001B 53                     push bx
:0001.001C B91001                 mov cx, 0110
:0001.001F 8A07                   mov al , [bx]
:0001.0021 C60700                 mov byte ptr [bx], 00
:0001.0024 3C00                   cmp al, 00
:0001.0026 7411                   je 0039
:0001.0028 B91000                 mov cx, 0010
:0001.002B 3C01                   cmp al, 01
:0001.002D 740A                   je 0039
:0001.002F B90001                 mov cx, 0100
:0001.0032 3C02                   cmp al, 02
:0001.0034 7403                   je 0039
:0001.0036 B90000                 mov cx, 0000

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:0001.0026(C), :0001.002D(C), :0001.0034(C)
|
:0001.0039 BAEB02                 mov dx, 02EB
:0001.003C 03D1                   add dx, cx
:0001.003E B080                   mov al, 80
:0001.0040 EE                     out dx, al
:0001.0041 BAE802                 mov dx, 02E8
:0001.0044 03D1                   add dx, cx
:0001.0046 B060                   mov al, 60
:0001.0048 EE                     out dx, al
:0001.0049 BAE902                 mov dx, 02E9
:0001.004C 03D1                   add dx, cx
:0001.004E B000                   mov al, 00
:0001.0050 EE                     out dx, al
:0001.0051 BAEB02                 mov dx, 02EB
:0001.0054 03D1                   add dx, cx
:0001.0056 B003                   mov al, 03
:0001.0058 EE                     out dx, al
:0001.0059 BAEC02                 mov dx, 02EC
:0001.005C 03D1                   add dx, cx
:0001.005E B003                   mov al, 03
:0001.0060 EE                     out dx, al
:0001.0061 BAE902                 mov dx, 02E9
:0001.0064 03D1                   add dx, cx
:0001.0066 B000                   mov al, 00
:0001.0068 EE                     out dx, al
:0001.0069 0E                     push cs
:0001.006A 1F                     pop ds
:0001.006B BAED02                 mov dx, 02ED
:0001.006E 03D1                   add dx, cx

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0001.009E(U)
|
:0001.0070 BE0300                 mov si, 0003
:0001.0073 B90A00                 mov cx, 000A

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:0001.0079(C), :0001.0086(C)
|
:0001.0076 EC                     in al, dx
:0001.0077 A820                   test al, 20
:0001.0079 74FB                   je 0076
:0001.007B 83EA05                 sub dx, 0005
:0001.007E 8A04                   mov al , [si]
:0001.0080 EE                     out dx, al
:0001.0081 83C205                 add dx, 0005
:0001.0084 46                     inc si
:0001.0085 49                     dec cx
:0001.0086 75EE                   jne 0076
:0001.0088 B96400                 mov cx, 0064

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0001.009C(C)
|
:0001.008B EC                     in al, dx
:0001.008C A801                   test al, 01
:0001.008E 740B                   je 009B
:0001.0090 83EA05                 sub dx, 0005
:0001.0093 EC                     in al, dx
:0001.0094 83C205                 add dx, 0005
:0001.0097 3CBB                   cmp al, BB
:0001.0099 7405                   je 00A0

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0001.008E(C)
|
:0001.009B 49                     dec cx
:0001.009C 75ED                   jne 008B
:0001.009E EBD0                   jmp 0070

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:0001.0099(C), :0001.00B4(C), :0001.00BA(C)
|
:0001.00A0 BE0D00                 mov si, 000D
:0001.00A3 B90800                 mov cx, 0008

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:0001.00A9(C), :0001.00BE(C)
|
:0001.00A6 EC                     in al, dx
:0001.00A7 A801                   test al, 01
:0001.00A9 74FB                   je 00A6
:0001.00AB 83EA05                 sub dx, 0005
:0001.00AE EC                     in al, dx
:0001.00AF 83C205                 add dx, 0005
:0001.00B2 3CBB                   cmp al, BB
:0001.00B4 74EA                   je 00A0
:0001.00B6 8A24                   mov ah, [si]
:0001.00B8 3AC4                   cmp al , ah
:0001.00BA 75E4                   jne 00A0
:0001.00BC 46                     inc si
:0001.00BD 49                     dec cx
:0001.00BE 75E6                   jne 00A6
:0001.00C0 B96400                 mov cx, 0064

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:0001.00C6(C), :0001.00D2(C)
|
:0001.00C3 EC                     in al, dx
:0001.00C4 A820                   test al, 20
:0001.00C6 74FB                   je 00C3
:0001.00C8 83EA05                 sub dx, 0005
:0001.00CB B0AA                   mov al, AA
:0001.00CD EE                     out dx, al
:0001.00CE 83C205                 add dx, 0005
:0001.00D1 49                     dec cx
:0001.00D2 75EF                   jne 00C3
:0001.00D4 5B                     pop bx
:0001.00D5 5B                     pop bx
:0001.00D6 1F                     pop ds
:0001.00D7 58                     pop ax
:0001.00D8 59                     pop cx
:0001.00D9 5A                     pop dx
:0001.00DA 07                     pop es
:0001.00DB CB                     retf

希望懂串硬件串口通讯的兄弟能给出注释
2009-8-18 17:51
0
雪    币:
能力值: (RANK: )
在线值:
发帖
回帖
粉丝
18
直接用IDA:
1. IDA认为你要加载的是一个Binary file, 选OK;
2. 接下来会问你要按32位还是16位文件处理, 选No按16位处理;
3. 然后有个提示(可能你已经关了)说加载了Binary file后按"C"可以切换成代码blablabla...的, 直接OK;
4. 进入主界面, 直接到seg0000:0000处按C, 所有代码就都出来了.

下面是关于两个BIN的说明:
ZO.BIN
seg000:0000           seg000          segment byte public 'CODE' use16
seg000:0000                           assume cs:seg000
seg000:0000                           assume es:nothing, ss:nothing, ds:nothing, fs:nothing, gs:nothing
seg000:0000 EB 13                     jmp     short loc_15

seg000:0002 90                        nop

seg000:0003 EE 30+    SendSign        db 0EEh, '06092791', 0EEh   //  0xEE是开始/结束向对方发送数据标识

seg000:000D 31 30+    RecvSign        db '10141491'

seg000:0015           loc_15:                                 ; CODE XREF: seg000:0000
seg000:0015 06                        push    es  // 保存环境
seg000:0016 52                        push    dx
seg000:0017 51                        push    cx
seg000:0018 50                        push    ax
seg000:0019 1E                        push    ds
seg000:001A 53                        push    bx
seg000:001B 53                        push    bx

seg000:001C B9 10 01                  mov     cx, 110h
seg000:001F 8A 07                     mov     al, [bx]  // 取参数: COM口
seg000:0021 C6 07 00                  mov     byte ptr [bx], 0  // 设返回值

seg000:0024 3C 00                     cmp     al, 0
seg000:0026 74 11                     jz      short loc_39  // COM0: CX = 0x110, 0x2E8 + 0x110 = 0x3F8
seg000:0028 B9 10 00                  mov     cx, 10h
seg000:002B 3C 01                     cmp     al, 1
seg000:002D 74 0A                     jz      short loc_39  // COM1: CX = 0x10, 0x2E8 + 0x10 = 0x2F8
seg000:002F B9 00 01                  mov     cx, 100h
seg000:0032 3C 02                     cmp     al, 2
seg000:0034 74 03                     jz      short loc_39  // COM2: CX = 0x100, 0x2E8 + 0x100 = 0x3E8
seg000:0036 B9 00 00                  mov     cx, 0         // COM3: CX = 0x0, 0x2E8 + 0x0 = 0x3E8

// 注意: 下面代码中以0x2E8为标准端口加一个差值做为最终端口, 以上这段代码求的是各COM口对应的端口与标准端口的差值
//       另外, 同一个端口, 在I/O状态下的定义是不同的, 甚至有些端口还依赖于其它端口的设置, 请注意看IDA给的提示.

seg000:0039           loc_39:                                 ; CODE XREF: seg000:0026
seg000:0039                                                   ; seg000:002D
seg000:0039                                                   ; seg000:0034
seg000:0039 BA EB 02                  mov     dx, 2EBh    // 0x2EB = 0x2E8 + 3, 其中0x2E8是基址, +3是line control register
seg000:003C 03 D1                     add     dx, cx      // 注意: 这里加上CX后就是对应的实际端口值
seg000:003E B0 80                     mov     al, 80h     // 设置了最高位, 即进入DLAB (Divisor Latch Access Bit)
seg000:0040 EE                        out     dx, al          ; COM: line control register bits:
seg000:0040                                                   ; 0-1: word length: 00=5, 01=6, 10=7, 11=8
seg000:0040                                                   ; 2:   stop bits: 0=1,1=2
seg000:0040                                                   ; 3-4: parity: x0=None, 01=Odd, 11=Even
seg000:0040                                                   ; 5:   stuck parity
seg000:0040                                                   ; 6:   enable break control. 1=start sending 0s (spaces)
seg000:0040                                                   ; 7:   DLAB (Divisor Latch Access Bit)
seg000:0041 BA E8 02                  mov     dx, 2E8h    // 0x2E8 = 0x2E8 + 0, 当DLAB生效时, +0是divisor latch low byte
seg000:0044 03 D1                     add     dx, cx      // 注意: 这里加上CX后就是对应的实际端口值
seg000:0046 B0 60                     mov     al, 60h     // 低字节是0x60
seg000:0048 EE                        out     dx, al          ; COM: transmitter holding register
seg000:0048                                                   ; or (when DLAB=1) divisor latch low byte.
seg000:0049 BA E9 02                  mov     dx, 2E9h    // 0x2E9 = 0x2E8 + 1, 当DLAB生效时 +1是divisor latch high byte
seg000:004C 03 D1                     add     dx, cx      // 注意: 这里加上CX后就是对应的实际端口值
seg000:004E B0 00                     mov     al, 0       // 高字节是0x00
seg000:0050 EE                        out     dx, al          ; COM: divisor latch high byte(when DLAB=1)
seg000:0050                                                   ; or interrupt enable register bits:
seg000:0050                                                   ; 0:1=an interrupt when rec'd data is available
seg000:0050                                                   ; 1:1=interrupt when transmit buffer is empty
seg000:0050                                                   ; 2:1=int on rec'r line status (error or break)
seg000:0050                                                   ; 3:1=int on modem status (CTS,DSR,RI,RLSD)

// 以上代码实现了将COM口设置成1200 bps (divisor latch = 0x0060)

seg000:0051 BA EB 02                  mov     dx, 2EBh    // 0x2EB = 0x2E8 + 3, +3是line control register
seg000:0054 03 D1                     add     dx, cx      // 注意: 这里加上CX后就是对应的实际端口值
seg000:0056 B0 03                     mov     al, 3       // 最高位清0, 即取消DLAB, 同时低两位为3, 其它们为0, 即8N1
seg000:0058 EE                        out     dx, al          ; COM: line control register bits:
seg000:0058                                                   ; 0-1: word length: 00=5, 01=6, 10=7, 11=8
seg000:0058                                                   ; 2:   stop bits: 0=1,1=2
seg000:0058                                                   ; 3-4: parity: x0=None, 01=Odd, 11=Even
seg000:0058                                                   ; 5:   stuck parity
seg000:0058                                                   ; 6:   enable break control. 1=start sending 0s (spaces)
seg000:0058                                                   ; 7:   DLAB (Divisor Latch Access Bit)

seg000:0059 BA EC 02                  mov     dx, 2ECh    // 0x2EC = 0x2E8 + 4, +4是modem control register
seg000:005C 03 D1                     add     dx, cx      // 注意: 这里加上CX后就是对应的实际端口值
seg000:005E B0 03                     mov     al, 3       // 激活DTR (data termnl ready)和RTS (request to send), 准备收发数据
seg000:0060 EE                        out     dx, al          ; COM: modem control reg bits:
seg000:0060                                                   ; 0: 1=activate -DTR (-data termnl ready), 0=deactivate
seg000:0060                                                   ; 1: 1=activate -RTS (-request to send), 0=deactivate
seg000:0060                                                   ; 2: 1=activate -OUT1 (spare, user-designated output)
seg000:0060                                                   ; 3: 1=activate -OUT2
seg000:0060                                                   ; 4: 1=activate loopback for diagnostic testing

seg000:0061 BA E9 02                  mov     dx, 2E9h    // 0x2E9 = 0x2E8 + 1, +1是interrupt enable register
seg000:0064 03 D1                     add     dx, cx      // 注意: 这里加上CX后就是对应的实际端口值
seg000:0066 B0 00                     mov     al, 0       // 禁用COM口中断, 即COM口不产生硬件中断
seg000:0068 EE                        out     dx, al          ; COM: divisor latch high byte(when DLAB=1)
seg000:0068                                                   ; or interrupt enable register bits:
seg000:0068                                                   ; 0:1=an interrupt when rec'd data is available
seg000:0068                                                   ; 1:1=interrupt when transmit buffer is empty
seg000:0068                                                   ; 2:1=int on rec'r line status (error or break)
seg000:0068                                                   ; 3:1=int on modem status (CTS,DSR,RI,RLSD)

// 初始化完毕, 接下来准备发数据

seg000:0069 0E                        push    cs
seg000:006A 1F                        pop     ds
seg000:006B BA ED 02                  mov     dx, 2EDh    // 0x2ED = 0x2E8 + 5, +5是line status register
seg000:006E 03 D1                     add     dx, cx      // 注意: 这里加上CX后就是对应的实际端口值

// 因为下面需要使用到cx, 所以这时dx固定成dx+cx的值, 然后根据需要直接对dx进行增减操作

seg000:0070           loc_70:                                 ; CODE XREF: seg000:009E
seg000:0070 BE 03 00                  mov     si, offset SendSign  // 要发送的数据
seg000:0073 B9 0A 00                  mov     cx, 0Ah              // 长度

seg000:0076           loc_76:                                 ; CODE XREF: seg000:0079
seg000:0076                                                   ; seg000:0086
seg000:0076 EC                        in      al, dx          ; COM: line status register bits:
seg000:0076                                                   ; 0: 1=data ready (DR)
seg000:0076                                                   ; 1: 1=overrun error (OE)
seg000:0076                                                   ; 2: 1=parity error (PE)
seg000:0076                                                   ; 3: 1=Bad stop bit in character
seg000:0076                                                   ; 4: 1=break indicated (BI)
seg000:0076                                                   ; 5: 1=transmitter holding register empty
seg000:0076                                                   ; 6: 1=transmitter empty
seg000:0077 A8 20                     test    al, 20h
seg000:0079 74 FB                     jz      short loc_76  // 检查COM口的状态寄存器, 直到bit5即transmitter holding register empty为真

// COM口说计算机可以发送数据给它

seg000:007B 83 EA 05                  sub     dx, 5      // 0x2ED - 5 = 0x2E8 + 0, +0是transmitter holding register
seg000:007E 8A 04                     mov     al, [si]   // 取当前数据并发送
seg000:0080 EE                        out     dx, al          ; COM: transmitter holding register
seg000:0080                                                   ; or (when DLAB=1) divisor latch low byte.

seg000:0081 83 C2 05                  add     dx, 5     // 恢复为line status register
seg000:0084 46                        inc     si        // 下一个数据
seg000:0085 49                        dec     cx        // 计数减1
seg000:0086 75 EE                     jnz     short loc_76   // 循环直到10个字节全部发送完毕

// OK, 10个字节全部发送完毕

seg000:0088 B9 64 00                  mov     cx, 64h   // 尝试100次

seg000:008B           loc_8B:                                 ; CODE XREF: seg000:009C
seg000:008B EC                        in      al, dx          ; COM: line status register bits:
seg000:008B                                                   ; 0: 1=data ready (DR)
seg000:008B                                                   ; 1: 1=overrun error (OE)
seg000:008B                                                   ; 2: 1=parity error (PE)
seg000:008B                                                   ; 3: 1=Bad stop bit in character
seg000:008B                                                   ; 4: 1=break indicated (BI)
seg000:008B                                                   ; 5: 1=transmitter holding register empty
seg000:008B                                                   ; 6: 1=transmitter empty
seg000:008C A8 01                     test    al, 1
seg000:008E 74 0B                     jz      short loc_9B  // 检查COM口的状态寄存器, 直到bit0即data ready(DR)为真

// COM口说有数据要发给计算机

seg000:0090 83 EA 05                  sub     dx, 5      // 0x2ED - 5 = 0x2E8 + 0, +0是receiver buffer register
seg000:0093 EC                        in      al, dx          ; COM: receiver buffer register.
seg000:0093                                                   ; 8 bits of character received.
seg000:0094 83 C2 05                  add     dx, 5     // 恢复为line status register

seg000:0097 3C BB                     cmp     al, 0BBh  // 读到的是0xBB吗? 0xBB是对方开始/结束发送数据标识
seg000:0099 74 05                     jz      short loc_A0
seg000:009B
seg000:009B           loc_9B:                                 ; CODE XREF: seg000:008E
seg000:009B 49                        dec     cx
seg000:009C 75 ED                     jnz     short loc_8B   // 不是, 计数器减1, 循环
seg000:009E EB D0                     jmp     short loc_70   // 100次了, 重新发送SendSign

// 谢天谢地, 终于收到了一个0xBB

seg000:00A0           loc_A0:                                 ; CODE XREF: seg000:0099
seg000:00A0                                                   ; seg000:00B4
seg000:00A0                                                   ; seg000:00BA
seg000:00A0 BE 0D 00                  mov     si, offset RecvSign  // 应该收到的数据
seg000:00A3 B9 08 00                  mov     cx, 8                // 长度

seg000:00A6           loc_A6:                                 ; CODE XREF: seg000:00A9
seg000:00A6                                                   ; seg000:00BE
seg000:00A6 EC                        in      al, dx          ; COM: line status register bits:
seg000:00A6                                                   ; 0: 1=data ready (DR)
seg000:00A6                                                   ; 1: 1=overrun error (OE)
seg000:00A6                                                   ; 2: 1=parity error (PE)
seg000:00A6                                                   ; 3: 1=Bad stop bit in character
seg000:00A6                                                   ; 4: 1=break indicated (BI)
seg000:00A6                                                   ; 5: 1=transmitter holding register empty
seg000:00A6                                                   ; 6: 1=transmitter empty
seg000:00A7 A8 01                     test    al, 1
seg000:00A9 74 FB                     jz      short loc_A6  // 检查COM口的状态寄存器, 直到bit0即data ready(DR)为真

seg000:00AB 83 EA 05                  sub     dx, 5
seg000:00AE EC                        in      al, dx          ; COM: receiver buffer register.
seg000:00AE                                                   ; 8 bits of character received.
seg000:00AF 83 C2 05                  add     dx, 5
seg000:00B2 3C BB                     cmp     al, 0BBh
seg000:00B4 74 EA                     jz      short loc_A0  // 又读到0xBB? 重来

seg000:00B6 8A 24                     mov     ah, [si]   // 当前应该读到的数据
seg000:00B8 3A C4                     cmp     al, ah
seg000:00BA 75 E4                     jnz     short loc_A0  // 不一样, 重来
seg000:00BC 46                        inc     si
seg000:00BD 49                        dec     cx
seg000:00BE 75 E6                     jnz     short loc_A6   // OK, 下一个, 直接读到RecvSign一样的数据

// OK, 接上头了

seg000:00C0 B9 64 00                  mov     cx, 64h   // 再来100次

seg000:00C3           loc_C3:                                 ; CODE XREF: seg000:00C6
seg000:00C3                                                   ; seg000:00D2
seg000:00C3 EC                        in      al, dx          ; COM: line status register bits:
seg000:00C3                                                   ; 0: 1=data ready (DR)
seg000:00C3                                                   ; 1: 1=overrun error (OE)
seg000:00C3                                                   ; 2: 1=parity error (PE)
seg000:00C3                                                   ; 3: 1=Bad stop bit in character
seg000:00C3                                                   ; 4: 1=break indicated (BI)
seg000:00C3                                                   ; 5: 1=transmitter holding register empty
seg000:00C3                                                   ; 6: 1=transmitter empty
seg000:00C4 A8 20                     test    al, 20h
seg000:00C6 74 FB                     jz      short loc_C3  // 检查COM口的状态寄存器, 直到bit5即transmitter holding register empty为真

// COM口说计算机可以发送数据给它

seg000:00C8 83 EA 05                  sub     dx, 5
seg000:00CB B0 AA                     mov     al, 0AAh      // 发送0xAA, 通知设备开始工作?
seg000:00CD EE                        out     dx, al          ; COM: transmitter holding register
seg000:00CD                                                   ; or (when DLAB=1) divisor latch low byte.
seg000:00CE 83 C2 05                  add     dx, 5
seg000:00D1 49                        dec     cx
seg000:00D2 75 EF                     jnz     short loc_C3  // 100次啊100次

seg000:00D4 5B                        pop     bx
seg000:00D5 5B                        pop     bx
seg000:00D6 1F                        pop     ds
seg000:00D7 58                        pop     ax
seg000:00D8 59                        pop     cx
seg000:00D9 5A                        pop     dx
seg000:00DA 07                        pop     es
seg000:00DB CB                        retf  // 恢复环境后返回
seg000:00DB           seg000          ends


ZY.BIN
seg000:0000           seg000          segment byte public 'CODE' use16
seg000:0000                           assume cs:seg000
seg000:0000                           assume es:nothing, ss:nothing, ds:nothing, fs:nothing, gs:nothing
seg000:0000 EB 01                     jmp     short loc_3

seg000:0002 90                        nop
seg000:0003

seg000:0003           loc_3:                                  ; CODE XREF: seg000:0000
seg000:0003 06                        push    es  // 保存环境
seg000:0004 52                        push    dx
seg000:0005 51                        push    cx
seg000:0006 50                        push    ax
seg000:0007 1E                        push    ds
seg000:0008 53                        push    bx
seg000:0009 53                        push    bx

seg000:000A B9 10 01                  mov     cx, 110h
seg000:000D 8A 07                     mov     al, [bx]  // 取参数: COM口
seg000:000F C6 07 00                  mov     byte ptr [bx], 0  // 设返回值

seg000:0012 3C 00                     cmp     al, 0
seg000:0014 74 11                     jz      short loc_27  // COM0: CX = 0x110, 0x2E8 + 0x110 = 0x3F8
seg000:0016 B9 10 00                  mov     cx, 10h
seg000:0019 3C 01                     cmp     al, 1
seg000:001B 74 0A                     jz      short loc_27  // COM1: CX = 0x10, 0x2E8 + 0x10 = 0x2F8
seg000:001D B9 00 01                  mov     cx, 100h
seg000:0020 3C 02                     cmp     al, 2
seg000:0022 74 03                     jz      short loc_27  // COM2: CX = 0x100, 0x2E8 + 0x100 = 0x3E8
seg000:0024 B9 00 00                  mov     cx, 0         // COM3: CX = 0x0, 0x2E8 + 0x0 = 0x3E8

// 注意: 下面代码中以0x2E8为标准端口加一个差值做为最终端口, 以上这段代码求的是各COM口对应的端口与标准端口的差值

seg000:0027           loc_27:                                 ; CODE XREF: seg000:0014
seg000:0027                                                   ; seg000:001B
seg000:0027                                                   ; seg000:0022
seg000:0027 BA ED 02                  mov     dx, 2EDh    // 0x2ED = 0x2E8 + 5, 其中0x2E8是基址, +5是line status register
seg000:002A 03 D1                     add     dx, cx      // 注意: 这里加上CX后就是对应的实际端口值
seg000:002C EC                        in      al, dx          ; COM: line status register bits:
seg000:002C                                                   ; 0: 1=data ready (DR)
seg000:002C                                                   ; 1: 1=overrun error (OE)
seg000:002C                                                   ; 2: 1=parity error (PE)
seg000:002C                                                   ; 3: 1=Bad stop bit in character
seg000:002C                                                   ; 4: 1=break indicated (BI)
seg000:002C                                                   ; 5: 1=transmitter holding register empty
seg000:002C                                                   ; 6: 1=transmitter empty
seg000:002D 8A E0                     mov     ah, al
seg000:002F F6 C4 01                  test    ah, 1
seg000:0032 74 0A                     jz      short loc_3E  // 检查COM口的状态寄存器, 直到bit0即data ready(DR)为真

seg000:0034 BA E8 02                  mov     dx, 2E8h    // 0x2E8 = 0x2E8 + 0, +0是receiver buffer register
seg000:0037 03 D1                     add     dx, cx      // 注意: 这里加上CX后就是对应的实际端口值
seg000:0039 EC                        in      al, dx          ; COM: receiver buffer register.
seg000:0039                                                   ; 8 bits of character received.
seg000:003A 24 7F                     and     al, 7Fh
seg000:003C 88 07                     mov     [bx], al  // 读一个字节, 去掉最高位后存到返回值的地址上

seg000:003E           loc_3E:                                 ; CODE XREF: seg000:0032
seg000:003E 5B                        pop     bx
seg000:003F 5B                        pop     bx
seg000:0040 1F                        pop     ds
seg000:0041 58                        pop     ax
seg000:0042 59                        pop     cx
seg000:0043 5A                        pop     dx
seg000:0044 07                        pop     es
seg000:0045 CB                        retf  // 恢复环境后返回
seg000:0045           seg000          ends
2009-8-20 20:47
0
雪    币:
能力值: (RANK: )
在线值:
发帖
回帖
粉丝
19
COM口由VFP里的全局变量 gcom 决定. 看你7楼的代码, 应该是COM1.


原始代码里有这个操作(参考ZY.BIN的003A处的代码), 我也不知道为什么.


你自己决定.


无用功.
2009-8-20 20:57
0
雪    币: 1889
活跃值: (193)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
20
谢arab,分析的很详细,正在由另一外兄弟写这个的dll在硬件上测试呢.
2009-8-21 16:05
0
雪    币: 201
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
21
只要有市场,就有生命力。
2009-10-29 10:14
0
游客
登录 | 注册 方可回帖
返回
//