作者TKyo (暗黑贵公子)
看板ASM
标题Re: [问题] 如何用组合语言写河内塔
时间Wed Nov 5 19:19:53 2008
※ 引述《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