2016-01-15 63 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