2012-05-17 1 views
3

В результате на мой пост Могу ли я использовать int21h для windows xp для печати?, я видел статью об использовании Windows API и в этой статье был ссылкой на использование API _WriteConsole @ 4 для печати сообщения на консоль. Статья находится в http://cs.lmu.edu/~ray/notes/x86assembly/.x86 assembly - как использовать 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.

Добавьте абсолютный путь в каталог masm32 \ include до masm32rt.inc. Пока вы на нем, откройте 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 содержит это уже и включает в себя include и includeselib для libs и включает в себя, которые широко используются. Мы используем его, чтобы сохранить кучу ввода.

Теперь откройте любой включенный файл в \ masm32 \ include включите, просто установите protos для вызовов API, чтобы вы могли использовать invoke для проверки параметров, а также псевдонимы вызовов API, поэтому нам не нужно вводить WriteConsoleA вместо этого мы просто пишем WriteConsole, вы даже можете сделать YoConsole equ, и в вашем коде вы должны написать YoConsole для WriteConsole.

Это, как говорится, мы не используем - Экстерн _WriteConsoleA @ 20: рядом как NASM бы ни мы должны установить нашу метку входа общественного MASM знает вашу точку входа на это:

.code 
yourentrypointname: 

end yourentrypointname 

мы также не нужно указывать libs для компоновщика, поскольку мы используем includeelib в нашем источнике.

Кроме того, НЕ повторяйте, НЕ ПРИНИМАЙТЕСЬ использовать привычные жесткие кодированные числа в своих параметрах. Выйди из этой привычки ТЕПЕРЬ !! Заголовочные файлы Windows используют DEFINES для удобства чтения кода. Мы (люди, которые вам помогают) не нуждаются в поиске того, что означает -11 для этого вызова API, я использовал определение, и вы знаете, что означает этот параметр. Плюс, что, если у вас есть, что вызов WriteConsole 40 раз? Если вы используете equate, вам нужно изменить только equate вместо поиска и замены. Если вы хотите, чтобы учебные пособия MASM искали Iczelion, они старые и содержат несколько ошибок, но они заставят вас начать, многие из нас в ранние годы использовали эти учебники.

+0

Что вы используете для создания и ссылки на этот файл? И я использовал командный файл для создания этого файла, я просто не установил переменную среды% path% в любые каталоги MASM. – Progrmr

+0

Я использовал именно ваш код, и он все еще говорит: 'can not open file: masm32rt.inc'. В моем командном файле я перехожу в каталог 'C: \ masm32 \ bin', а затем я делаю' ml/c/coff test.asm'. Затем я делаю 'cd C: \ masm32 \ bin' и do' link/subsystem: console C: \ masm32 \ inc \ masm32rt.inc test.obj'. Это верно? Если нет, можете ли вы опубликовать пошаговый способ сделать это? – Progrmr

+0

Поцарапайте мои последние два комментария, заставил его работать. Спасибо за ваше время. – Progrmr

0

Вы можете попробовать MASM32, вот привет мир пример консольного приложения:

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

    .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 

Но если вы хотите, чтобы придерживаться текущей ассемблере, мы можем посмотреть под макросом.мас есть макрос печати:

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

Итак, вы хотите STDOUT, в 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, или я могу буквально заменить WriteFile для WriteConsole с тем же синтаксисом, и он будет работать? – Progrmr

+0

И я использую MASM32 – Progrmr

+0

Я просто пробовал использовать 'WriteFile' в своей программе, и он не компилировался. Это дало мне ошибку: «undefined external». Не могли бы вы дать мне код, чтобы показать мне, что делать? – 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

Использует ли это API окон или макрос мазмы? – Progrmr

+0

И что вы скомпилировали? Я попробовал скомпилировать его с этим: 'ml test.asm/c' и' link test.obj C: \ masm32 \ include \ masm32rt.inc/подсистема: console' Это не сработало. Он сказал: 'не могу открыть файл: masm32rt.inc'. – Progrmr

+0

В конце концов я получил его, чтобы пройти мимо части 'ml', но затем, когда дело дошло до ссылки, оно произнесло« недопустимый или поврежденный файл ». Почему это? – Progrmr