汉气猗亡

镜像:https://leisurebamboo.wordpress.com/2023/10/06/tc2
汉气猗亡——汉化 turbo c 2.01 札记·完蛋日·祭念borland·杂感。
原文在2010-1-1 发表于 http://www.aogosoft.com/bbs/view.asp?id=89992 ,现有增删。
"汉化"(Sinicization)暂定义为“函数名、变量名、宏名 能用汉字”。

完蛋日。杂感。borland忘却的纪念。
  borland的IDE部门被分割、卖出未逾一年,borland已被focus收购了,我也有写一点东西的必要了。

  这次的汉化,选的是Turbo c 2.01版,可在
http://edn.embarcadero.com/museum/内找到。通过链接
http://cc.codegear.com/Free/tc201,可以得到
http://altd.embarcadero.com/download/museum/tc201.zip
(看到 embarcadero 这個词,回想borland当年,唏嘘不已)。
其内含有 2.01版的tcc.exe,长度为 18'0385字节。

  ㈠将该exe文件的 2a506h~2a585h 偏移处的内容,由原来的80h个“EE”改为80h个“F6”;
将该exe文件的 2a606h~2a685h 偏移处的内容,由原来的80h个“E6”改为80h个“F6”
(更改理由见附录),即可实现汉字函数名、变量名的正常编译。

  ㈡.将该exe文件的 2c00dh~2c08ch 偏移处的内容,由原来的80h个“00”改为80h个“08”(更改理由见附录),
宏的左半阕(例如 #define 汉字 abc)即可使用汉字。

  ㈢.将该exe文件的 19d85h~19da1h 偏移处的内容,
由原来的    “8C 46 FE, 89 5E FC 33, F6 EB 04 FF
46 FC 46 C4, 5E FC 26 80, 3F 00 74 06, 26 F6 07 80
74 ED”
    改为  “31 F6 26, 8A 07 08 C0, 74 0E 79 08
3C 90 72 08, 3C FC 73 04, 46 43 EB EB, 8C 46 FE 89
5E FC”(更改理由见附录),
宏的右半阕(例如 #define inc 汉字++ )即可使用汉字。

  ㈣.将该exe文件的 1a084h~1a0b3h 偏移处的内容,
由原来的  “8B 56 FA 8B, C3 3B 16 B6, 74 75 16 3B
06 B4 74 75, 10 C4 5E F4, 8C 06 3A 50, 89 1E 38 50
EB 03 FF 46, F4 C4 5E F4, 26 80 3F 00, 74 06 26 F6
07 80 74 EE”
    改为“66 8B 46 F8, C4 5E F4 66, 3B 06 B4 74
75 08 8C 06, 3A 50 89 1E, 38 50 26 8A, 07 0A C0 74
0D 79 08 3C, 90 72 07 3C, FC 73 03 43, EB EC 89 5E
F4 90 90 90” (更改理由见附录),以免取词出错。

  ㈤.改完了。

  至此,tcc.exe 2.01 版本汉化完毕,函数名、变量名、宏 均能用汉字。但为便于日後tc编译链接,命名时请仍沿用下划线 或英文字母开头。

  本文的反响,可能是芸芸的在校学子感觉受到了蛊惑(因为不少高校仍沿用turbo c教学)。但如我旧贴所说,更多的肯定是“前辈的不齿、同侪的嘲讽、后学的误解”。
  编译器的生命,毕竟受到商业推动的影响。也祗有商业产品,才会提供足够的文档、用例、在线帮助,并对广大的用户群形成吸引力、赢取其对产品的预期信心。但商业过程通常与产品质量关系不大,对程序员而言最可怕者也是这一点,他们祗能将宝压在大公司身上。
  然而,即使强如borland这般的强者,也居然垮了。敢于反抗“雷蒙德的暴君”的队伍中,骤然失去了一面(哪怕仅仅是精神上的)旗帜。
  思之黯然,遂有本文悲观的题目。

  以下是 更改tcc.exe的原因 与 所涉的反汇编代码。各位 觉得它厌烦的读贴人士,请关闭本窗口。
  具体的asm,可参阅https://sourceforge.net/projects/difc/files/turbo_c/2.0/
附录:

tcc.exe的编译部分为:
cs:077268A07 B400 AL=ES:[BX],AH=0;即c=fgetch()
cs:07C8946FC [BP-04]=AX
cs:07F8B1ED450 BX=wo[50D4];分枝枚举表==30B6h
cs:083035EFC + wo[BP-4]
cs:0868A07 AL=[BX];即enum=分枝枚举表[c]
cs:08898 8946FE CBW, [BP-02]=AX
cs:08C2DE0FF AX+=20
cs:08F3D2000 7603 E9F800if(AX>=20)JMP 018F
cs:0978BD8 D1E3 BX=AX<<1
cs:09B2E FFA7A000 JMP CS:00A0[BX]

  其中 wo[50D4]==30B6h,为《分枝枚举表》首址,内共有100h个字节,取值从-19h(0e7h)到29h 不等。其详细内容为:
db 8 dup(0EEh) ;00~07
db 0EEh,4 dup(-9),0ech,2 dup(0EEh) ;08~0F
db 8 dup(0EEh) ;10~17
db 2 dup(0EEh),0E7h,5 dup(0EEh) ;18~1f
db -9,0,0F4h,2 dup(0EEh),-1,-2,0F2h;20~27
db 1,2,-3,-4,8,0F1h,0F0h,-5 ;28~2f
db 0Ah dup(0F5h) ;'0' ~ '9'
db 1Fh,7,0EFh,0F8h,0EDh,1Eh ;3A~3F
db 0EEh,1Ah dup(0F6h) ;'@', 'A'~'Z'
db 3, 0EAh,4, 0FAh, 0F6h ;5B~5F
db 0EEh,1Ah dup(0F6h) ;60, 'a'~'z'
db 5, 0F9h,6, 29h, 0EEh ;7B~7F
db 80h dup(0EEh) ;80~FF

  将《分枝枚举表》的後半阕(即ds:3136h~31b5h的内容,对应为本exe文件的 2a506h~2a585h 偏移处的内容),
改作80h个“在表中常见的”f6,即可实现汉字函数名、变量名的正常编译。
  但当 wo[50D4]==31B6h 时,《分枝枚举表》的後半阕(即ds:3236h~32b5h的内容,对应为本exe文件的 2a606h~2a685h 偏移处的内容),
就成了db 80h dup(0E6h),亦须改作80h个“在表中常见的”f6。



宏定义时的strcpy函数片段为:
cs:B17A02424 do{....
cs:B278A4604  AL=c; //AL=[BP+04]
cs:B2AC45EFC  es:bx=dst; //LES BX,[BP-4]
cs:B2D268807 FF46FC  *(dst++)=AL; //ES:[BX]=AL, wo[BP-4]++
...
cs:B43C41E3850  es:bx=src; //LES BX,[5038]
cs:B47FF063850  src++; //INC wo[5038]
cs:B4B268A07 B400  ax=*src; //AL=ES:[BX],AH=00
cs:B50894604 8B5E04  c=ax;//BX=[BP+04]=AX
cs:B56F687BD4B0E 75BA  }while(attr[c]&0x0E //TEST by 4BBD[BX],0E, JNZ B17
cs:B5D83FB5F 74B5  || c=='_' //CMP BX,5F, JZ B17
cs:B6283FB24 74B0  || c=='$'); //CMP BX,24, JZ B17

其中ds:[4bbd~4cbc] 为《宏内ascii码对应属性表》,其具体内容为:
db  8 dup(20h) ;00~07
db 20h,21h,21h ;08~0A
db  5 dup(20h) ;0B~0F
db  8 dup(20h) ;10~17
db  8 dup(20h) ;18~1F
db 1,7 dup(0) ;20~27
db  8 dup(0) ;28~2F
db 0Ah dup(2) ;'0'~'9'
db  6 dup(0) ;3A~3F
db 0,6 dup(14h) ;'@',"ABCDEF"
db 20 dup(4) ;'G'~'Z'
db  5 dup(0) ;5B~5F
db 0,6 dup(18h) ;60,"abcdef"
db 20 dup(8) ;'g'~'z'
db  4 dup(0) ;7B~7E
db 20h ;7F
db 80h dup(0) ;80~FF

  汉字的属性在 ds:[4c3d~4cbc]内。原文的该部分为全零,导致“宏的名含有汉字”时定义出错。
  汉化方法仍是将ascii(80~FF)的对应属性部分(位于tcc.exe的第[2c00dh~2c08ch]字节,原文为80h个“00”),换为80h dup(8),即可实现汉字宏名的正常编译。



而宏替换时调用的strlen函数片段为:
cs:3858C46FE 895EFC p=es:bx; //[BP-2]=ES, [BP-4]=BX
cs:38B33F6 EB04 strlen=0; //SI=0, JMP 0393
cs:393C45EFC //LES BX,[BP-04]
cs:39626803F00 7406 while(p[0]!='\0' //CMP by ES:[BX],00,JZ 3A2
cs:39C26F60780 74ED && (p[0]&80h)==0) //TEST by ES:[BX],80,JZ 38F
cs:38FFF46FC  {p++; //INC wo[BP-04]
cs:39246  strlen++; //INC SI
 }
cs:3A2C45EF4 ……
在39c的那一句 会 导致“宏的内容含有汉字”时会替换出错。

  拟整段改为:
cs:38531f6 strlen=0;//SI=0
cs:387268A07 do{ //AL=ES:[BX]
cs:38A08C0 740E  if(*p=='\0')break;//OR AL,AL, JZ 39C
cs:38E7908  else if(p[0]&80h//    JNS 398
cs:3903C90 7208   &&(p[0]<90h)//if(AL<90)JB 39C
cs:3943CFC 7304   ||p[0]>=FCh))break;//if(al>=FC)jae 39C
cs:39846 43  else{strlen++; p++};//SI++, BX++
cs:39AEBEF  }while(1);//JMP 387
cs:39C8C46FE 895EFCp=es:bx;//[BP-2]=ES, [BP-4]=BX
cs:3A2C45EF4……



而取另一词调用的next_word函数片段为:
cs:6848B56FA 8BC3 //dx=[bp-06]; ax=bx
cs:6893B16B674 7516if(lp8==g_74b6)//cmp dx, [74B6], jne 6A5
cs:68F3B06B474 7510 //cmp ax, [74B4], jne 6A5
cs:695C45EF4  { //les bx, [bp-0C]
cs:6988C063A50 891E3850 g_5038=lpC;//[503A]=es; [5038]=bx
cs:6A0EB03  }; //jmp 6A5
cs:6A5C45EF4 //les bx, [bp-0C]
cs:6A826803F00 7406while(lpC[0]!='\0'//cmp by es:[bx],00; je 6B4
cs:6AE26F60780 74EE && (lpC[0]&80h)==0)//test by es:[bx],80; je 6A2
cs:6A2FF46F4  lpC++; //inc wo[bp-0C]
cs:6B4C45EF8 ……
  若有某字符>=80,则断句出错。

  拟改作:
cs:684668B46F8 //eax=lp8;//[bp-08]
cs:688C45EF4 p=lpC; //les bx,lpC
cs:68B663B06B474 if(lp8==g_74b6) //cmp eax,[74B4]
cs:6907508 //jne 69A
cs:6928C063A50  g_5038=lpC; // [503A]=es
cs:696891E3850 // [5038]=bx
cs:69A268A07 do{ //al=p[0];//es:[bx]
cs:69D0AC0 740D  if(p[0]=='0')break; //or al,al; je 6AE
cs:6A17908  else if(p[0]&80h //     jns 6AB
cs:6A33C90 7207  && (p[0]<90h //cmp al,90; jb 6AE
cs:6A73CFC 7303   || p[0]>=FCh))break;//cmp al,FC; jnb 6AE
cs:6AB43  else p++; //inc bx
cs:6ACEBEC  }while(1); //jmp 69A
cs:6AE895EF4 lpC=p; //[bp-0C]=bx
cs:6B190 90 90 //nop
cs:6B4C45EF8 ……



  回想borland当年,雄姿英发。多少次与微软浴血奋战,
如许力求完美的编译速度、和集成开发环境。让无数程序员
祗要一想到Borland,就油然而生出一股朝圣般的孺慕和崇敬。
其多平台开发工具的用户达到320多万,遍及29个以上的国家。
JBuilder、Java开发工具、Delphi与C++Builder、研发出来
未久的PHP与Ruby的IDE开发工具……还有本文提及的Turbo C。
  往昔的辉煌,去岁出卖了IDE部门,今年卖了自己。
覆辙重蹈,何其之促。美人迟暮,英雄末路。
  难道这就是x86商业编译器的下场吗?难道大家都要退到
单片机或者开源的战线上去了吗?
  默哀一分钟……

评论

此博客中的热门博文

我的开源软件项目(不定期更新)

heavy metal war 配音评论

tww2