Re: [問題] 如何用組合語言寫河內塔
※ 引述《hijamoya (阿瑋)》之銘言:
: 用C語言很快就能寫出來河內塔的程式....只要用遞回就可以了,但是,我將他改成
: 組合語言之後就會出問題...#include <stdio.h>
: #include<stdlib.h>
: void hanoi(int n, char A, char B, char C)
: {
: if(n == 1)
: printf("Move sheet %d from %c to %c\n", n, A, C);
: else
: {
: hanoi(n-1, A, C, B);
: printf("Move sheet %d from %c to %c\n", n, A, C);
: hanoi(n-1, B, A, C);
: }
: }
: int main()
: {
: int n;
: printf("請輸入盤數:");
: scanf("%d", &n);
: hanoi(n, 'A', 'B', 'C');
: system("pause");
: return 0;
: }
: 這是我寫的C語言..要怎麼寫成組合語言呢
: 希望大家幫幫忙/.\
: PS:我是用Masm615去編譯的
我不知道你出的問題在哪 ...
所以剛剛我就無聊, 依照你的程式, 稍微翻譯改編了一下 ...
原始碼如下:
.386P
.MODEL flat, stdcall
OPTION casemap:none
INCLUDE ..\..\MASM32\INCLUDE\windows.inc
INCLUDE ..\..\MASM32\INCLUDE\kernel32.inc
INCLUDE ..\..\MASM32\INCLUDE\user32.inc
INCLUDELIB ..\..\MASM32\LIB\kernel32.lib
INCLUDELIB ..\..\MASM32\LIB\user32.lib
hanoi PROTO :DWORD, :BYTE, :BYTE, :BYTE
stdIn PROTO :DWORD, :DWORD
stdOut PROTO :DWORD
atodw PROTO :DWORD
myPause PROTO
CR = 0dh
LF = 0ah
.DATA
szWaitInputMsg BYTE "請輸入盤數:", 0
szWaitKeyMsg BYTE "請按任意鍵繼續...", 0
szHanniFmt BYTE "Move sheet %d from %c to %c", CR, LF, 0
szMsvcrtDllName BYTE "msvcrt.dll", 0
szSystemFunc BYTE "system", 0
szSystemCmd BYTE "pause",0
.CODE
main PROC
LOCAL szBuffer[80]:BYTE
LOCAL num:DWORD
INVOKE stdOut, ADDR szWaitInputMsg
INVOKE stdIn, ADDR szBuffer, SIZEOF szBuffer
INVOKE atodw, ADDR szBuffer
mov num, eax
INVOKE hanoi, num, 'A', 'B', 'C'
INVOKE myPause
INVOKE ExitProcess, 0
main ENDP
hanoi_stdout PROC num:DWORD, charA:BYTE, charC:BYTE
LOCAL szBuffer[80]:BYTE
movzx eax, charC
push eax
movzx eax, charA
push eax
push num
push OFFSET szHanniFmt
lea eax, szBuffer
push eax
call wsprintf
add esp, 14h
INVOKE stdOut, ADDR szBuffer
ret
hanoi_stdout ENDP
hanoi PROC USES ebx num:DWORD, charA:BYTE, charB:BYTE, charC:BYTE
.IF (num == 1)
INVOKE hanoi_stdout, num, charA, charC
.ELSE
mov ebx, num
dec ebx
INVOKE hanoi, ebx, charA, charC, charB
INVOKE hanoi_stdout, num, charA, charC
mov ebx, num
dec ebx
INVOKE hanoi, ebx, charB, charA, charC
.ENDIF
ret
hanoi ENDP
stdIn PROC lpszBuffer:DWORD, nReadLength:DWORD
LOCAL hConsole:DWORD
LOCAL bRead:DWORD
INVOKE GetStdHandle, STD_INPUT_HANDLE
mov hConsole, eax
INVOKE SetConsoleMode, hConsole, ENABLE_ECHO_INPUT or \
ENABLE_LINE_INPUT or ENABLE_PROCESSED_INPUT
INVOKE ReadFile, hConsole, lpszBuffer, nReadLength, \
ADDR bRead, NULL
mov eax, bRead
ret
stdIn ENDP
stdOut PROC lpszText:DWORD
LOCAL hConsole:DWORD
LOCAL nWriteLength:DWORD
LOCAL bWritten:DWORD
INVOKE GetStdHandle, STD_OUTPUT_HANDLE
mov hConsole, eax
INVOKE lstrlen, lpszText
mov nWriteLength, eax
INVOKE WriteFile, hConsole, lpszText, nWriteLength, \
ADDR bWritten, NULL
mov eax, bWritten
ret
stdOut ENDP
atodw PROC USES ecx edx esi edi lpszNumber:DWORD
cld
xor eax, eax
xor ecx, ecx
xor edx, edx
mov esi, lpszNumber
lodsb
.IF (al == '-')
lodsb
not edx
.ENDIF
.WHILE (al >= '0' && al <= '9')
sub al, '0'
lea ecx, dword ptr [ecx + 4 * ecx]
lea ecx, dword ptr [eax + 2 * ecx]
lodsb
.ENDW
lea eax, dword ptr [edx + ecx]
xor eax, edx
ret
atodw ENDP
myPause PROC
LOCAL hLibrary:DWORD
INVOKE LoadLibrary, ADDR szMsvcrtDllName
.IF (eax != NULL)
mov hLibrary, eax
INVOKE GetProcAddress, hLibrary, ADDR szSystemFunc
.IF (eax != NULL)
push OFFSET szSystemCmd
call eax
.ENDIF
INVOKE FreeLibrary, hLibrary
.ENDIF
ret
myPause ENDP
END main
--
私が生存への道は
今も未來も唯一つ
私自身の闇黑のためだ
即ち「ハ・ル・ヒ」
--
※ 發信站: 批踢踢實業坊(ptt.cc)
◆ From: 203.187.0.206
討論串 (同標題文章)
ASM 近期熱門文章
PTT數位生活區 即時熱門文章