2016-01-15 61 views
0

使用masm32進行彙編編碼。使用masm32進行彙編編碼

如何將一個值放入一個變量中,該變量不是在.data段中定義的,而是由LOCAL中的decleration定義的?
古都:

.486          
.model flat, stdcall      
option casemap :none      

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

include \masm32\include\masm32.inc 
include \masm32\include\gdi32.inc 
include \masm32\include\user32.inc 
include \masm32\include\kernel32.inc 

includelib \masm32\lib\masm32.lib 
includelib \masm32\lib\gdi32.lib 
includelib \masm32\lib\user32.lib 
includelib \masm32\lib\kernel32.lib 


.data 

.code 

start: 

call main 
exit 

main proc 

LOCAL dewit:DWORD 

mov dewit, 0 
print dewit 

ret 

main endp 

end start 

我想是這樣的:

Mov dewit, 0 

它沒有工作。但是,此代碼:

Mov dewit, input("enter a number") 

是否已將值放入其中。

有人嗎?

**本地刪除只能在一個過程中

+0

'MOV [DEWIT],0 高級宏觀幫助描述也許'MOV字PTR [DEWIT] 0'?還要定義「_didn't work_」。 – Jester

+0

沒有工作 - 即它遇到了錯誤,我想..該程序'停止工作'在那一點 – daniel

+0

這是不夠的信息,提供[mcve]。您也可以查看生成的彙編代碼。另外,考慮不要使用幫助器功能,直到您也可以手動完成,並瞭解彙編器在做什麼。 – Jester

回答

0

由於您使用MASM32如果你想打印出一個32位的值嘗試str$做這種方式:

print str$(dewit) 

這32位值的內存位置dewit轉換成字符串,並且該字符串被打印在控制檯上。這也要求立即值以及工作:

print str$(100) 

和寄存器:

print str$(eax) 

,如果你要打印的無符號值可以使用$ustr爲好。

這些宏在隨MASM32 SDK

+0

酷!現在如果我想打印一個單詞怎麼辦?因爲我看到,就像你說的那樣,它會打印存儲在變量中的*數字的值.. – daniel

+0

@daniel您可以將單詞從內存中移動到32位寄存器使用類似[movsz](http://x86.renejeschke.de/html/file_module_x86_id_206.html)指令的符號,該符號可以將一個16位寄存器或存儲器操作數擴展到一個32位寄存器中。那32位寄存器可以用於'str $' –

+0

@daniel:我可能誤解了。你的意思是_WORD_的值是16位還是像「你好」? –

2

您可以通過調試器找到它。下面是一個調試器查看的代碼的開頭:

CPU Disasm 
Address Command         Comments 
00401000 CALL 0040100C       ; call main 
00401005 PUSH 0         ; /ExitCode = 0 
00401007 CALL <JMP.&kernel32.ExitProcess>   ; \KERNEL32.ExitProcess 
0040100C PUSH EBP         ; main 
0040100D MOV EBP,ESP 
0040100F ADD ESP,-4 
00401012 MOV DWORD PTR SS:[LOCAL.1],0    ; dewit = 0 
00401019 PUSH DWORD PTR SS:[LOCAL.1]    ; /Arg1 => 0 
0040101C CALL 00401024       ; print 
00401021 LEAVE 
00401022 RETN 

所以print叫(請記住,print是一個宏觀的,所以它的擴展編譯一次)。 Remeber你推0至print

CPU Disasm 
Address Command         Comments 
00401024 PUSH EBP         ; print (guessed Arg1) 
00401025 MOV EBP,ESP 
00401027 ADD ESP,-0C 
0040102A PUSH -0B         ; /StdHandle = STD_OUTPUT_HANDLE 
0040102C CALL <JMP.&kernel32.GetStdHandle>  ; \KERNEL32.GetStdHandle 
00401031 MOV DWORD PTR SS:[LOCAL.1],EAX 
00401034 PUSH DWORD PTR SS:[Arg1]     ; /Arg1 => [Arg1] *** push 0 *** 
00401037 CALL 00401060       ; \so.00401060 

見行0x00401034,0被推爲一個調用的參數。

讓我們來看看代碼:

CPU Disasm 
Address Command         Comments 
00401060 MOV EAX,DWORD PTR SS:[Arg1]    ; eax = 0 
00401064 LEA EDX,[EAX+3] 
00401067 PUSH EBP 
00401068 PUSH EDI 
00401069 MOV EBP,80808080 
0040106E /MOV EDI,DWORD PTR DS:[EAX]    ; trying to dereference [0]... 

代碼功能是在地址0(又名空指針錯誤),這是一個很大的閱讀,不,不。

看着print宏在macros.asm,看來這個宏沒有做任何格式化,你應該用printf

您的代碼固定的(你需要printf宏,msvcrt.incmsvcrt.lib仍處於macros.asm定義):

.486          
.model flat, stdcall      
option casemap :none      

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

include \masm32\include\masm32.inc 
include \masm32\include\gdi32.inc 
include \masm32\include\user32.inc 
include \masm32\include\kernel32.inc 

includelib \masm32\lib\msvcrt.lib 
includelib \masm32\lib\masm32.lib 
includelib \masm32\lib\gdi32.lib 
includelib \masm32\lib\user32.lib 
includelib \masm32\lib\kernel32.lib 
includelib \masm32\lib\masm32.lib 


.data 
format_string db "value: %d", 0 

.code 

start: 

    call main 
    exit 

main proc 

    LOCAL dewit:DWORD 

    mov dewit, 0 
    print "printing value: " 
    printf ("value: %d", dewit) 

    ret 

main endp 

end start 

大致沒有任何相同的代碼包括:

; compile and link with: 
; ml test.asm /link /subsystem:console /defaultlib:kernel32.lib /defaultlib:msvcrt.lib 

.686 
.model flat, stdcall 
option casemap: none 

ExitProcess PROTO STDCALL :DWORD 

externdef _imp__printf:PTR c_msvcrt 
crt_printf equ <_imp__printf> 

.data 
fmt db "value: %d", 0 

.code 
start: 
    call MyFunc 
    invoke ExitProcess, 0 
    ret 


MyFunc proc 
    LOCAL foo:DWORD 

    mov foo, 42 

    push foo 
    push offset fmt 
    call crt_printf 

    ret 
MyFunc endp 

end start 

我也完全同意@Jester:

另外,consi明鏡不使用輔助功能,直到你可以用手 做到這一點,並瞭解彙編做

宏是偉大的,但除非你能理解他們做什麼,實現手工一樣,你應該避免使用它們。他們從初學者眼中隱藏太多東西。

+0

謝謝!這將花費我一段時間檢查出所有你說..但它有幫助 – daniel

+0

Btw,哪個調試器使用?.. @neitsa – daniel

+0

@daniel:代碼片段摘自[ollybg](http:// www。 ollydbg.de/) – Neitsa