String 复制字符串时出错-ASM

String 复制字符串时出错-ASM,string,assembly,masm,x86,String,Assembly,Masm,X86,我正在研究一本汇编手册,程序将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 BYT

我正在研究一本汇编手册,程序将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
我试图调试它,但当完成循环时,程序出现访问错误。我不明白为什么。 请帮忙。 调试:

多谢各位

==========

解决方案 我对代码进行了一些编辑,但还是一样的

.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
循环永远不会结束。 编辑:实际上它结束了

以下是您可以做到的:

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

循环退出后,没有任何东西可以终止程序。它必须显式地调用“exit program”系统调用,或者返回给调用者,或者在结束时执行它应该执行的任何操作


正如所写的,它只是在
循环
指令之外继续执行内存,执行发生在那里的字节指令。那肯定不是你想要的。

是的,我没有叫出口。 嗯,我已经编程了一个退出,但是我想在完成循环时执行一个打印(StdOut)我是如何做到这一点的?实际上程序不会打印字符串,因为没有执行标准输出

Cyril Fougeray:我有同样的问题,循环有一个条件(ECX)


移动字符串是常用的操作,因此在x86汇编中它有自己的机器指令:

start:
    mov esi,OFFSET origen
    mov edi,OFFSET destino
    mov ecx,SIZEOF destino
    cld 
    rep movsb
    ret
您应该去掉意大利面条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仍然没有输出,请参见 在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
有关这些Windows功能的更多信息,请参阅

我8天前看到这个问题,以为你已经解决了。沃利一开始基本上是正确的

您的应用程序在代码执行后继续处理垃圾代码,因为它没有被告知何时停止=给自己找一个好的反汇编程序。由于您不使用堆栈,并且它保持平衡,所以只需在代码之后提供一个“retn”

使用Windows库(您在MASM下发布)通常会发出内核32中包含的“invoke ExitProcess”

以下内容将按预期工作(但不会输出任何内容,因为您没有指定需要):


这似乎不是问题所在。
循环
指令递减ecx。如果它不是零或低于零(我忘了是哪个),它就会跳到标签上。“循环”会在循环之前检查“ecx”。循环将正常终止,但循环后的行为未定义。非常感谢:),但我需要使用循环指令执行此操作。我需要:复制字符串,打印字符串和退出。我怎么能做到?
  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
.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