閱讀862 返回首頁    go 阿裏雲 go 技術社區[雲棲]


[探討/原創] 關於 HLA 的學習心得

 最近我看到不少兄弟在問關於 HLA 學習的事,他們大多買了<<匯編語言編程藝術>>
這本書,作者是美國的 Randall Hyde。這本書寫的總的來說還是不錯的。剛開始的
時候比較簡單,有些簡單的地方又說的略顯囉嗦。但如果你耐心看一段時間就能體會
其中樂趣。雖然該書有些地方講的讓初學者感到困惑:比如講到 類和對象匯編實現
的時候,開始的一大部分用來做上機實操時得到關於類方法的執行都是會出錯的,因為
有個關鍵地方沒有設置,即:

而這個設置在後麵才會講到,但開始卻沒有絲毫提起,所以會讓很多人以為是hla
實現上有問題,其實不然。
當然本書自身翻譯的不自然和漏字錯字也還是存在的,這也算翻譯作品的通病吧。而
且譯者好像缺乏了一點幽默感(我沒看過英文原著),但從某些句子段落的咀嚼似乎
又能讓你會到原作作者的幽默天才(很多原作作者的語言都是很生動和詼諧幽默的,
例如另一本:<<WIN32 API 編程 for VB>>)。但不管如何該書還是很有看頭的,其中
還探討了使用 HLA 強大的編譯時語言編寫高級語言語法的功能,還有浮點指令,MMX
指令的用法,類和對象的實現等等。

我寫此作的目的是希望正在學習 HLA 的朋友能夠將遇到的問題和學習的經驗和心得和
大家共享,本人才疏學淺,通假字連篇,所以不當之處懇請各位多多指出,在此謝過了。

我想先拋磚引玉先說2點:
   <<匯編語言編程藝術>> 這本書中使用的是 masm32 的編譯器,但書中對 win32 SDK
   編程好像隻是一筆帶過,並無詳細說明,我在這裏就先給出對於 win32 SDK 的簡單
   實現,相信大家可以舉一反三:

//* * * * * * * * * * * * * *
//code by hopy|侯佩         *
//to use Win32 API with HLA *
//2006-07-12                *
//* * * * * * * * * * * * * *

programWin32ApiNow;
#include("w.hhf");
#include("wpa.hhf");

const
txt:string:="I'm Hopy";
cp:string:="windows XP";

beginWin32ApiNow;
w.MessageBox(NULL,txt,cp,w.MB_OK);
endWin32ApiNow;

  關於 enum 的研究。書上 P154 頁略微提到了一點 HLA 對枚舉表達的實現,但作者
  同時指出內部是使用 8bits 變量存放 enum 的元素,所以enum元素數量不能超過
  256個,有趣的是在 P155 頁的腳注上作者卻提示:HLA 提供了一個機製,該機製可以
  指定 enum 數據類型占用 2 個或 4 個字節的空間,到此本書再也閉口不提如何達到
  該目的。那麼到底可不可以讓枚舉占用超過1字節的空間呢?

  我在 HLA 編程指南中找到這麼一段話(原話):
 
  By default, HLA uses eight-bit values to represent enumerated data types.
This means that you can represent up to 256 differentsymbols using an
enumerated data type. This should prove sufficient for most applications.
HLA provides a special"compile-time variable" that lets you change the size
of an enumerated type from one to two or four bytes. In theory, all you’
vegot to do is assign the value two or four to this variable and HLA will automatically resize the storage for enumerated types tohandle longer
lists of objects. In practice, however, this feature has never been tested
so it’s questionable if it works well. If youneed enumerated lists with
more than 256 items, you might consider using HLA const definitions rather
than an enum list, just to be on the safe side. Fortunately, the need for
such an enum list is exceedingly remote.

HLA 自動地根據 enum 元素的數量改變空間的大小,理論上可以支持超過 256 個枚舉
元素。但實際上不管怎樣這個特性從來沒有被測試過,它有可能工作不正常。如果您要
創建超過 256 個枚舉元素,您可能在 const 段中定義更好一些...

觀看不試是沒有用的,下麵我創建了一個含有 500 個元素的 enum 類型,為了簡便起
見,我使用了 HLA 的編譯時語言的支持,而不是真的手工輸入500個元素(誰叫偶懶哩):

program EnumTest;
#include("stdlib.hhf");

type
//以下是創建500個元素的 color 枚舉:
color:enum{
?i:=0;
#while(i<500)
@text("a"+ string(i)+",")
?i:=i+1;
#endwhile
a500
 };

static
EC:color:=a500;

begin EnumTest;
//nothing...
end EnumTest;

F:/HLA>hla a.hla
 Assembling: a.asm
a.data.inc(2) : error A2071: initializer magnitude too large for specified size
Error returned by Assembler = 1

program EnumTest;
#include("stdlib.hhf");

type
//以下是創建500個元素的 color 枚舉:
color:enum{
?i:=0;
#while(i<500)
@text("a"+ string(i)+",")
?i:=i+1;
#endwhile
a500
};

static
EC:word:=a500;

begin EnumTest;
//nothing...
end EnumTest;

3 關於 HLA 中的 intmul 指令,大家如果在 intel 指令手冊中找的話,結果可能會
  失望,因為沒有該條指令。其實他隻是 imul 的變種(異型?)之一:

4 在看到移位指令的時候,我就在想是否可以不用位指令來實現移位(bt之類的指令
  也不用)。答案是肯定的,以下是左移一位的代碼:

programmainmy;
#include("stdlib.hhf");

readonly
bitstr:byte[8]:=[%0000_0001,%0000_0010,%0000_0100,
        %0000_1000,%0001_0000,%0010_0000,
        %0100_0000,%1000_0000];

var
mb:byte;

procedurelm1(var mb:byte);
var
tmpa:byte;
tmpb:byte;
tmpi32:int32;
beginlm1;
push(eax);
push(ebx);
mov(mb,eax);
mov([eax],al);
mov(al,tmpb);
mov(al,tmpa);

mov(6,tmpi32);
while(tmpi32>=0) do
mov(tmpi32,ebx);
and(bitstr[ebx],al);
mov(bitstr[ebx+1],al);
jnzt0;
not(al);
and(al,tmpb);
jmpt1;
t0:
or(al,tmpb);
t1:
dec(tmpi32);
mov(tmpa,al);
endwhile;

and(%1111_1110,tmpb);
mov(mb,eax);
mov(tmpb,bl);
mov(bl,[eax]);
pop(ebx);
pop(eax);
end         lm1;

mov(%0101_0111,mb);
stdout.put("the value before transfer is ",mb,nl);
lm1(mb);
stdout.put("after transfer the value is ",mb,nl);

endmainmy;

  我在上麵說過了 HLA 的編譯時語法的功能是很強的,現在做一個小的實例是通過
  編譯時宏將 ascii字符串 轉換成 寬字符串。要說明的是這個轉換很簡單,隻是一
  個小例子其中還有很多沒考慮到的地方:

programtest0;
#include("stdlib.hhf");

#macroctrlstr(thestr);
?maxlen:=@length(thestr);
?i:=0;
@text("ustr:char[maxlen*2+2]:=[")
#while(i<maxlen)
?strnow:=@substr(thestr,i,1);
@text("#0,'"+strnow+"',")
#print(strnow)
?i:=i+1;
#endwhile
@text("#0,#0];")
#endmacro;

static
ctrlstr("kinds");

endtest0;

 

最後更新:2017-04-02 00:06:17

  上一篇:go 類似TM名片對方形象tabctrl(屬性頁)的實現
  下一篇:go [準備/原創]:親身體驗多核/超線程