2013-04-29 21:21:30Morris

[組合語言][作業] Macros 改寫前一份作業

Problem

—As for HW#2, replace procedure calls with macro calls.
—以作業2的程式碼為基礎,將上次的字串處理procedure改寫為marco的形式

助教提示:

—MACRO是什麼
用高階語言C++來舉例,如同#define的功能一樣,是屬於前置處理指令。
它會
MACRO的呼叫指令展開成多行程式碼放在主程式裡面。
—將程式碼改成MACRO形式以後就無法組譯了
程式碼改寫為MACRO後,通常遇到的問題可能是MACRO程式裡面有用到Label(也就是同學常命名為L1L2的東西)。因為程式碼中可能使用MACRO不只一次,但是組譯器本來就不允需同樣的Label出現兩次以上,所以組譯不通過,所以要用一個叫LOCAL的指令來解決這個問題,課本或投影片也都有提到。
另一個可能是MACRO展開後程式指令長度超過label±127 bytes跳躍長度限制。

心得

重新撰寫了一次程式碼,以 esi, edi 原本的意思撰寫,思路比較清晰,而同時在呼叫 function 
的時候進行輸出,雖然以函數的功能不應該去做這些。修改程 MACRO 時,特別要記得將 ret 給註解掉
,否則會直接結束程式,除了標頭與結尾的地方要按照 MACRO 處理,還記得要將一些 local label
宣告在 MACRO 中,以 LOCAL … 的方式命名。
同時補充一下期中考卷中的心得,助教特別有講到如果是在 .data 中的識別字,
會直接在 mov 中被辨識其形態,因此當使用無法辨識的時候,最好還是使用
TPYE PTR [address] 的形式去撰寫。







TITLE ; use MACRO replace PROC by function using.

INCLUDE Irvine32.inc
.data
BStr0 db 01111110b
BStr1 db 10000001b
BStr2 db 10100101b
BStr3 db 10000001b
BStr4 db 10100101b
BStr5 db 10111101b
BStr6 db 10000101b
BStr7 db 01111110b
CStr0 db 8 dup(?)
CStr1 db 8 dup(?)
CStr2 db 8 dup(?)
CStr3 db 8 dup(?)
CStr4 db 8 dup(?)
CStr5 db 8 dup(?)
CStr6 db 8 dup(?)
CStr7 db 8 dup(?)
.code
convertPattern MACRO ; PROC ; if we use PROC
; bl = binary integer, edi = write destination
LOCAL L1, L2
    push ecx
    push edi
   
    mov ecx, 8             ; number of bits in BL
L1: shl bl, 1              ; shift high bit into carry flag
    mov BYTE PTR[edi], ' ' ; choose ' ' as default output
    mov al, ' '
    jnc L2                 ; if no Carry, jump L2
    mov BYTE PTR[edi], '*' ; else move '*' to buffer
    mov al, '*'
L2: inc edi                ; next written byte
    call WriteChar         ; printf("%c", al);
    loop L1                ; shift another bit to left
   
    pop edi
    pop ecx
    ; ret ; if we use PROC
ENDM ;convertPattern ENDP ; if we use PROC

start PROC
    mov ecx, 8            ; run BStr[0-7]
    mov esi, OFFSET BStr0 ; move source
    mov edi, OFFSET CStr0 ; move destination
   
L1: mov bl, BYTE PTR [esi]; move byte [esi] to bl
    ;call convertPattern  ; PROC pattern
    convertPattern
    add esi, TYPE BStr0   ; next source
    add edi, SIZEOF CStr0 ; next destination
    call Crlf             ; println
    loop L1
   
    call WaitMsg
    invoke ExitProcess, 0
start ENDP;
end start;