我正在研究一本装配书,而且,该程序将origen中包含的字符串复制到destino。程序编译没有错误,但当我执行它时,Windows说:“程序需要关闭”。
我正在编写IA-32程序集,并使用Qeditor进行编译。
这是代码:
.386
.model flat,stdcall
option casemap:none
.data
origen BYTE "Esta es la cadena de origen",0 ; "This is the source string",0
destino BYTE SIZEOF origen DUP(0)
.code
start:
mov esi,0 ; index register
mov ecx,SIZEOF origen ; loop counter
L1:
mov al,origen[esi] ; obtain a character from origen
mov destino[esi],al ; store character in destino
inc esi ; move to next character
loop L1 ; repeat the process for all characters contained in the string
END start
我试过调试它,但是当完成循环时,程序有访问错误。我不明白为什么。 请帮忙。 调试:http://www.subirimagenes.com/otros-captura1-8802120.html
谢谢。
==========
我编写了一些代码,但是相同。
.386
.model flat,stdcall
option casemap:none
include \masm32\include\kernel32.inc
include \masm32\include\masm32.inc
includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\masm32.lib ; StdIn, StdOut
.data
origen BYTE "Hello world.",0
destino BYTE SIZEOF origen DUP(0)
.code
main PROC
mov esi,0 ; registro índice
mov ecx,LENGTHOF origen ; ECX = 12 veces
bucle:
mov al,[origen + esi]
mov [destino + esi],al
add esi,TYPE origen
loop bucle
; Wheen loop finish, execute this:
invoke StdOut, OFFSET destino ; print
invoke ExitProcess, 0 ; exit
main ENDP
END main
答案 0 :(得分:3)
循环退出后没有任何东西可以终止程序。它必须显式调用“退出程序”系统调用,或者返回调用者,或者它结束时应该做的任何事情。
正如所写的那样,它只是继续执行超出loop
指令的内存,无论发生在那里的字节是什么。那肯定不是你想要的。
答案 1 :(得分:0)
循环永远不会结束。 编辑:实际上它结束了。
您可以这样做:
mov esi,0 ; index register
mov ecx,SIZEOF origen ; loop counter
L1:
mov al,origen[esi] ; obtain a character from origen
mov destino[esi],al ; store character in destino
inc esi ; move to next character
cmp esi, ecx ; set flags
jne L1 ; repeat the process for all characters contained in the string if index != size
END start
答案 2 :(得分:0)
Cyril Fougeray :有了这个我有同样的问题,而且LOOP有一个条件(ECX)。
.386
.model flat,stdcall
option casemap:none
include \masm32\include\windows.inc
include \masm32\include\kernel32.inc
include \masm32\include\masm32.inc
includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\masm32.lib ; StdIn, StdOut
.data
origen BYTE "Esta es la cadena de origen",0
destino BYTE SIZEOF origen DUP(0)
.code
start:
mov esi,0
mov ecx,SIZEOF origen
jmp L1
invoke StdOut, OFFSET destino
invoke ExitProcess, 0
L1:
mov al,origen[esi]
mov destino[esi],al
inc esi
loop L1
END start
答案 3 :(得分:0)
移动字符串是经常使用的操作,因此它在x86汇编中有自己的机器指令:
start:
mov esi,OFFSET origen
mov edi,OFFSET destino
mov ecx,SIZEOF destino
cld
rep movsb
ret
答案 4 :(得分:0)
你应该摆脱 spaghetti jmp L1 ,否则你的过程永远不会在循环结束后调用StdOut :
.data
origen BYTE "Esta es la cadena de origen",0
destino BYTE SIZEOF origen DUP(0)
BytesWritten DWORD 0
.code
start:
mov esi,0
mov ecx,SIZEOF origen
L1:
mov al,origen[esi]
mov destino[esi],al
inc esi
loop L1
invoke StdOut, OFFSET destino
invoke ExitProcess, 0
如果调用MASM的宏 StdOut 仍然没有输出,请参阅 masm32 invoking stdout gives no output 在Windows中,我更喜欢本地写入标准输出的方法:
invoke GetStdHandle,STD_OUTPUT_HANDLE ; get standard output handle to EAX
invoke WriteFile,EAX,OFFSET destino, SIZEOF origen,OFFSET BytesWritten,0 ; write destino to StdOut
有关theese Windows功能的更多信息,请参阅 http://msdn.microsoft.com/en-us/library/windows/desktop/ms683231%28v=vs.85%29.aspx http://msdn.microsoft.com/en-us/library/aa910675.aspx
答案 5 :(得分:0)
我在8天前看到了这个问题并假设你已经解决了。基本上Wally在开始时是正确的。
你的应用程序在代码执行后继续处理垃圾代码,因为它没有被告知何时停止=给自己一个好的反汇编程序。由于您没有使用堆栈并且它保持平衡,您只需在代码后提供“retn”。
使用Windows库(您在MASM下发布)通常会发出kernel32中包含的“调用ExitProcess”。
以下内容将按预期工作(但不会输出任何内容,因为您未指定需要):
.386
.MODEL flat, stdcall
OPTION CASEMAP:NONE
.data
origen db "Esta es la cadena de origen",0 ; Source string zero terminated
destino db SIZEOF origen dup(0) ;Buffer zero initialised
.code
Start:
xor esi,esi ;esi = 00000000
xor eax,eax ;eax = 00000000
mov ecx,sizeof origen ;loop counter
L1:
mov al,origen[esi] ;get a byte from esi (character from 'origen')
mov destino[esi],al ;store byte (character) in 'destino'
inc esi ;move to next byte (character)
loop L1
retn ;magic instruction!
End Start