进展缓慢

这几天开始做汇编方面的支持, 进展比较缓慢, 主要有以下问题:

  • MinGW 上编译比较缓慢, 导致 configure 非常慢, 难以忍受.
  • 莫名奇妙的问题比较多, 感觉上跟 Windows 关系比较大, configure.in 文件必须得 UNIX 格式, 如果是 DOS 格式就会出错. 现在 X86 上的汇编单独测试的结果是没有问题的, 但是运行在 MAC 中就会出现 CRC 校验错误, 打出的 log 中间前面一部分是对的, 中间有个值错了一点点, 不知道到底是哪里出错了.
  • 对汇编不熟, 写起来比较费劲. X86 的还好, 直接把原来的拷贝过来, 稍微改改就可以了. X86_64 就差一些了, 得看很多文档.

继续努力, 现在在考虑是先把 Win32 上搞好呢, 还是先把 ADM64 弄好.

Win32 上的完成了

写完以后再仔细看了一下, 在 Win32 上的汇编中自己犯了一个愚蠢的错误, 原来的代码中有一个跳转是 jle, 需要改成 jge, 而我写成了 jg, 这样当等于 0 的时候就错了, 从而导致微小的错误, 但足以让 CRC 验证通不过. 说明单元测试狠重要, 最好覆盖所有的用例, 象这里我等于零的情况自己就没测试到.

而 AMD64 上则是非常诡异, 如下的汇编代码:

  1. GLOBAL OKOK
  2. GLOBAL _OKOK
  3.  
  4. OKOK:
  5. _OKOK:  
  6.         cmp  rdi, byte 0       ; nDirection
  7.         jge  short SUB_L
  8. ADD_L:  
  9.         mov rax, 1
  10.         ret
  11. SUB_L:  
  12.         je short DONE
  13.         mov rax, -1
  14.         ret
  15. DONE:  
  16.         mov rax, 0
  17.         ret

调用如下:

  1.     int result =  OKOK(-8, SIZE);
  2.     printf("result -1 = %d\n", result);
  3.  
  4.     result =  OKOK(8, SIZE);
  5.     printf("result 1 = %d\n", result);
  6.    
  7.     result =  OKOK(0, SIZE);
  8.     printf("result 0 = %d\n", result);

理论上应该是: 如果第一个参数小于零, 则结果为 1, 如果等于零,, 结果为 0, 如果大于零, 结果为 -1. 运行的结果是不管大于零小于零都是 -1. 很奇怪.

GDB 的调试结果

  1. Breakpoint 1, 0x0000000000400c40 in _OKOK ()
  2. (gdb) disassemble
  3. Dump of assembler code for function _OKOK:
  4. 0x0000000000400c40 <_OKOK+0>:   cmp    $0x0,%rdi
  5. 0x0000000000400c44 <_OKOK+4>:   jge    0x400c4e <_OKOK+14>
  6. 0x0000000000400c46 <_OKOK+6>:   mov    $0x1,%rax
  7. 0x0000000000400c4d <_OKOK+13>:  retq  
  8. 0x0000000000400c4e <_OKOK+14>:  je     0x400c58 <_OKOK+24>
  9. 0x0000000000400c50 <_OKOK+16>:  mov    $0xffffffffffffffff,%rax
  10. 0x0000000000400c57 <_OKOK+23>:  retq  
  11. 0x0000000000400c58 <_OKOK+24>:  mov    $0x0,%rax
  12. 0x0000000000400c5f <_OKOK+31>:  retq  
  13. End of assembler dump.
  14. (gdb) info registers rdi eflags
  15. rdi            0xfffffff8       4294967288
  16. eflags         0x202    514
  17. (gdb) si
  18. 0x0000000000400c44 in _OKOK ()
  19. (gdb) info registers rdi eflags
  20. rdi            0xfffffff8       4294967288
  21. eflags         0x302    770
  22. (gdb) si
  23. 0x0000000000400c4e in _OKOK ()

看到这个结果, 就更诧异了, 第一个 si 以后, eflags 变成了 0x302, 也就是说 OF(第 11 位)为 0, SF (第 7 位) 也为 0, 而 JGE 发生的条件是 SF == OF. 这就奇怪了, SF 位应该是 1 的呀(-8 - 0 = -8, 结果是负数, SF 应置 1).

AMD64 汇编问题解决

昨天在 comp.lang.asm.x86 上发了求助贴, 今天有人回了:

  1. On AMD64 int is 32-bit. When passing parameters ints are zero exteneded
  2. to 64-bits. So, if you pass int to a routine expecting 64-bit parameter
  3. the passed int will be always non-negative.
  4.  
  5. To get expected result either make OKOK int 32-bit routine (replace rdi
  6. by edi) or declare its parameter as long.

回头想想, 一方面读手册不仔细, 另外一方面其实从 GDB 的结果是可以看出来的, rdi 是 64 位寄存器, 显示出来的结果应该是 0xfffffffffffffff8(-8), 而实际上显示出来的是 0xfffffff8(4294967288), 在这一点上大大疏忽了. 多读文档, 多仔细读文档.

嗨!说句题外话

SuperMMX老兄,
如果有时间,
请看看mac插件源码的下载链接,
无法下载的。
谢谢!

不好意思

找到下载点了;
现在xmms2已经出了0.2,
要是老兄能写个xmms2的mac插件就好了

下载与 xmms2

下载以后本站不再提供, 都扔到 Sourceforge.

xmms2 其实我去年已经做了, 已经提交到 [XMMS2 bug tracker], 分别是 [#363][#210]. 但由于当时的 XMMS2 架构不好, 同步有些 bug, 此插件还不能完全正确工作.

后来机器坏掉就再没做了, 现在也没有自己的 Linux 桌面, 所以只好搁浅.

Post new comment

The content of this field is kept private and will not be shown publicly.
  • Allowed HTML tags: <a> <em> <strong> <cite> <code> <ul> <ol> <li> <dl> <dt> <dd> <blockquote>
  • You can enable syntax highlighting of source code with the following tags: <code>, <blockcode>. Beside the tag style "<foo>" it is also possible to use "[foo]".
  • You can use BBCode tags in the text. URLs will automatically be converted to links.
  • Web page addresses and e-mail addresses turn into links automatically.
  • Lines and paragraphs break automatically.

More information about formatting options

CAPTCHA
This question is for testing whether you are a human visitor and to prevent automated spam submissions.
(minus fifteen) plus equals 51
Solve this math question and enter the solution with digits. E.g. for "two plus four = ?" enter "6".