2013-04-29 21:21:30Morris
[組合語言][作業] Macros 改寫前一份作業
Problem
助教提示:
會直接在 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;
As for HW#2, replace
procedure calls with macro calls.
以作業2的程式碼為基礎,將上次的字串處理procedure改寫為marco的形式
助教提示:
MACRO是什麼
◦用高階語言C++來舉例,如同#define的功能一樣,是屬於前置處理指令。
它會MACRO的呼叫指令”展開”成多行程式碼放在主程式裡面。
它會MACRO的呼叫指令”展開”成多行程式碼放在主程式裡面。
將程式碼改成MACRO形式以後就無法組譯了
◦程式碼改寫為MACRO後,通常遇到的問題可能是MACRO程式裡面有用到Label(也就是同學常命名為L1、L2、…的東西)。因為程式碼中可能使用MACRO不只一次,但是組譯器本來就不允需同樣的Label出現兩次以上,所以組譯不通過,所以要用一個叫LOCAL的指令來解決這個問題,課本或投影片也都有提到。
◦另一個可能是MACRO展開後程式指令長度超過label的±127 bytes跳躍長度限制。
心得
重新撰寫了一次程式碼,以 esi, edi 原本的意思撰寫,思路比較清晰,而同時在呼叫 function同時補充一下期中考卷中的心得,助教特別有講到如果是在 .data 中的識別字,
的時候進行輸出,雖然以函數的功能不應該去做這些。修改程 MACRO 時,特別要記得將 ret 給註解掉
,否則會直接結束程式,除了標頭與結尾的地方要按照 MACRO 處理,還記得要將一些 local label
宣告在 MACRO 中,以 LOCAL … 的方式命名。
會直接在 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;