2012-05-17 41 views
3

結果發佈到我的文章我可以在windows xp上使用int21h來打印東西嗎?,我看過一篇關於使用Windows API的文章,並且在這篇文章中提到使用_WriteConsole @ 4 API將消息打印到控制檯。文章在http://cs.lmu.edu/~ray/notes/x86assembly/x86彙編 - 如何使用Windows API _WriteConsole @ 4 - masm32語法

這是到目前爲止我的代碼:

.386P 
.model flat 
extern [email protected]:near 
extern [email protected]:near 
extern [email protected]:near 
public _go 

.data 
     msg  byte 'if you get this, it worked.', 10 
     handle dword ? 
     written dword ? 
.code 
start: 
_go:  
     push -11 
     call [email protected] 
     mov  handle, eax 
     push 0 
     push offset written 
     push 13 
     push offset msg 
     push handle 
     call [email protected] 
     push 0 
     call [email protected] 
end start 

我使用這個語法編譯代碼: ML:

ml (the file is called test.asm) test.asm /c 

鏈接:

link test.obj C:\masm32\lib\kernel32.lib /SUBSYSTEM:CONSOLE /entry:go 

我已經得到了它來編譯和鏈接,但是當我運行產生的.exe時,它完全沒有任何作用,甚至不會出現錯誤轉。控制檯只是黑色。爲什麼是這樣?

任何幫助將不勝感激。對於這個論壇的用戶,我爲每天轟炸stackoverflow.com道歉,這只是我有很少的資源可以學習。

由於提前,

Progrmr

+0

適用於Visual Studio 2010(10.00.40219.01),儘管您應該將'13'調整爲msg的實際長度。 – DCoder

+0

真的嗎?我正在使用命令提示符並在帖子中鍵入'ml'和'link'字符串。我怎麼能得到這個工作? – Progrmr

回答

2

首先,您獲得示例代碼的鏈接來自NASM用戶,他可能從未使用過他所說的MASM。他還將他的MASM樣本寫成NASM格式。您想使用Assembly的事實意味着您必須是高級計算機用戶。您需要知道如何使用批處理文件,如何設置系統路徑和其他內容。當出現問題時,你通過研究學習。所以你得到一個錯誤,說它找不到masm32rt.inc,但你說你正在使用MASM32。我使用批處理文件和IDE進行彙編,我的系統路徑指向MASM32中的各個目錄。

在masm32rt.inc之前添加masm32 \ include目錄的絕對路徑。當你在它的時候,在文本編輯器中打開masm32rt.inc,看看裏面有什麼 - 修正了錯誤。

You start your source file with: 
.586 
.option casemap:NONE 
.model flat, stdcall 

include yourincludeshere and it could be a bunch 
includelib yourlibshere same here a bunch 

masm32rt.inc已經包含它,它包含libs的include和includelib,還包括被廣泛使用的include。我們用它來保存一堆輸入。

現在在\ masm32 \ include中打開任何包含文件包括只是爲API調用設置原型,以便您可以使用invoke進行參數檢查,它還會別名API調用,所以我們不必鍵入WriteConsoleA相反,我們只是寫WriteConsole地獄,你甚至可以做YoConsole equ,並且在你的代碼中你會爲WriteConsole寫YoConsole。

話雖這麼說,我們不使用 - EXTERN _WriteConsoleA @ 20:就近NASM將我們也不需要把我們的入境標籤設置爲公共MASM知悉這你的切入點:

.code 
yourentrypointname: 

end yourentrypointname 

我們因爲我們在我們的源代碼中使用includelib,所以也不必將鏈接庫指定給鏈接器。

另外,不要,我重複不要養成在參數中使用硬編碼數字的習慣。現在擺脫這種習慣! Windows頭文件使用DEFINES的原因 - 代碼的可讀性,我們(幫助你的人)不需要查找-11意味着什麼API調用,我使用了define並且你知道那個參數意味着什麼。另外如果你有WriteConsole調用40次?如果你使用equate,你需要改變equate而不是搜索和替換。 如果你想體面MASM教程搜索Iczelion他們是舊的,幷包含一些錯誤,但他們會讓你開始,我們很多人在早期使用這些教程。

+0

你用什麼來製作和鏈接這個文件?我一直在使用批處理文件來創建這個文件,我只是沒有將我的%path%環境變量設置爲任何MASM目錄。 – Progrmr

+0

我完全使用你的代碼,它仍然說'無法打開文件:masm32rt.inc'。在我的批處理文件中,我切換到目錄'C:\ masm32 \ bin',然後執行'ml/c/coff test.asm'。然後我做'cd C:\ masm32 \ bin'並執行'link/subsystem:console C:\ masm32 \ inc \ masm32rt.inc test.obj'。它是否正確?如果沒有,你可以一步一步地發佈這樣做嗎? – Progrmr

+0

劃傷我最後兩條評論,讓它工作。謝謝你的時間。 – Progrmr

0

你可以嘗試MASM32,這裏是控制檯應用程序一個Hello World例子:

; ««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««« * 

    .486 
    .model flat, stdcall 
    option casemap :none ; case sensitive 

; ««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««« 

    include \masm32\include\windows.inc 
    include \masm32\include\masm32.inc 
    include \masm32\include\kernel32.inc 
    include \masm32\macros\macros.asm 

    includelib \masm32\lib\masm32.lib 
    includelib \masm32\lib\kernel32.lib 

    .code 

start: 

; ««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««« 

    print "Hello world" 

    exit 

; ««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««« 

end start 

但是,如果你要堅持你目前的彙編,我們可以看看macros.asm下有一個打印宏:

print MACRO arg1:REQ,varname:VARARG  ;; display zero terminated string 
    invoke StdOut,reparg(arg1) 
    IFNB <varname> 
    invoke StdOut,chr$(varname) 
    ENDIF 
ENDM 

所以你要標準輸出在MASM32它看起來像這樣:

StdOut proc lpszText:DWORD 

    LOCAL hOutPut :DWORD 
    LOCAL bWritten :DWORD 
    LOCAL sl  :DWORD 

    invoke GetStdHandle,STD_OUTPUT_HANDLE 
    mov hOutPut, eax 

    invoke StrLen,lpszText 
    mov sl, eax 

    invoke WriteFile,hOutPut,lpszText,sl,ADDR bWritten,NULL 

    mov eax, bWritten 
    ret 

StdOut endp 

所以在這個旅程的終點​​,你必須使用WriteFile的不WriteConsole :)

+0

WriteFile和WriteConsole之間的語法是否有任何區別,或者我可以使用相同的語法將WriteConsole換成WriteConsole,它可以工作嗎? – Progrmr

+0

而我正在使用MASM32 – Progrmr

+0

我剛剛在我的程序中使用'WriteFile',並沒有編譯。它給了我一個錯誤,即:「未定義的外部」。你能給我一些代碼來告訴我該怎麼做嗎? – Progrmr

2

這工作沒有任何問題:

include masm32rt.inc 

.data 
szMsg  db "I am in the console!", 0 
MSG_LEN  equ $ - szMsg 

.data? 
BytesWriten dd ? 

.code 
start: 
    push STD_OUTPUT_HANDLE 
    call GetStdHandle 

    push NULL 
    push offset BytesWriten 
    push MSG_LEN 
    push offset szMsg 
    push eax 
    call WriteConsole 

    push 0 
    call ExitProcess 
end start 

你的入口標籤是_go,但你告訴鏈接器是go -/entry:去創建控制檯但不執行任何代碼!在這種情況下,您不需要告訴鏈接器入口點,您的入口點就是開始......鏈接器如何知道?結束開始

+0

這是否使用Windows API或masm庫文件宏? – Progrmr

+0

你是怎麼編譯的?我試着編譯它:'ml test.asm/c'和'link test.obj C:\ masm32 \ include \ masm32rt.inc/subsystem:console'它不起作用。它說'無法打開文件:masm32rt.inc'。 – Progrmr

+0

我最終通過'ml'部分,但是當它連接時,它說'無效或損壞的文件'。爲什麼是這樣? – Progrmr