Windows(x86)程序集向输入的字符串追加空终止符
我当前正在尝试向(a?)用户输入的字符串追加空终止符:Windows(x86)程序集向输入的字符串追加空终止符,windows,string,assembly,x86,append,Windows,String,Assembly,X86,Append,我当前正在尝试向(a?)用户输入的字符串追加空终止符: .386 .model flat, stdcall WriteFile PROTO STDCALL:DWORD, :PTR, :DWORD, :PTR DWORD, :PTR OVERLAPPED ReadFile PROTO STDCALL:DWORD, :PTR, :DWORD, :PTR DWORD, :PTR OVERLAPPED GetStdHandle PROTO STDCALL:DWORD .data buff
.386
.model flat, stdcall
WriteFile PROTO STDCALL:DWORD, :PTR, :DWORD, :PTR DWORD, :PTR OVERLAPPED
ReadFile PROTO STDCALL:DWORD, :PTR, :DWORD, :PTR DWORD, :PTR OVERLAPPED
GetStdHandle PROTO STDCALL:DWORD
.data
buff DB 100h DUP(?)
stdInHandle DWORD 0
bytesRead DWORD ?
.code
start:
;read string from stdin
INVOKE GetStdHandle, -10
MOV stdInHandle, eax
INVOKE ReadFile, stdInHandle, BYTE PTR[buff], 100, ADDR bytesRead, 0
;append null terminator on CR,LF
MOV eax, bytesRead
MOV edx, BYTE PTR[buff]
SUB eax, 2
AND BYTE PTR [eax+edx], 0
RET
END start
它拒绝在MOV-edx,BYTE PTR[buff]
处组装,并给我一个错误:错误:操作码和操作数的组合无效(或CPU设置错误)。
所以我假设我不能将MOV
字节PTR[buff]的值写入寄存器edx。因此,我甚至无法开始测试这种尝试将NULL
终止符应用于字符串的方法是否有效
我的问题是,上面的代码有什么问题(我应该使用不同的寄存器而不是edx吗?)
对字符串应用
NULL
终止符的最佳方法是什么 不能将字节值移动到dword大小的寄存器中。您需要使用字节大小的寄存器,如dl
,或者使用movzx
对其进行零扩展。在处理字节时,我建议使用第一个选项。不能将字节值移动到dword大小的寄存器中。您需要使用字节大小的寄存器,如dl
,或者使用movzx
对其进行零扩展。当您使用字节时,我建议您使用第一个选项。这非常常见,因此MASM32运行时将此功能作为其运行时的一部分提供。您只需包含相关代码:
include \masm32\include\masm32rt.inc
然后使用StripLF
功能,如下所示:
invoke StripLF, addr buff
要解决当前问题(如果您想手动执行),您需要将buff
的地址改为edx
mov edx, offset buff
这是如此常见,以至于MASM32运行时将此功能作为其运行时的一部分提供。您只需包含相关代码:
include \masm32\include\masm32rt.inc
然后使用StripLF
功能,如下所示:
invoke StripLF, addr buff
要解决当前问题(如果您想手动执行),您需要将buff
的地址改为edx
mov edx, offset buff
当我必须为字符串创建方法而不使用good ole Irvine中的任何内容时,我得到了字符串的长度,将返回的长度(需要为空终止符添加一个额外的+1)增加1,然后在指针位于计数器所在的字符串末尾添加0h
MOV EAX, SIZEOF lpSourceString + 1 ; Get the string length of string, add 1 to include null-terminator
INVOKE allocMem, EAX ; Allocate memory for a target to copy to
LEA ESI, [lpSourceString] ; put source address in ESI
MOV EDI, EAX ; copy the dest address to another register we can increment
MOV ECX, SIZEOF lpSourceString ; Set up loop counter
我们有绳子的大小。现在我们可以将null终止添加到它。为此,我们需要确保有一个指针指向字符串的末尾。因此,如果我们有一个在EAX中返回字符串的方法,EAX需要指向字符串的开头(因此我们不修改allocMem
,而是增加EDI中的副本)。假设我们将字符放入字符串中:
nextByte: ; Jump label, get the next byte in the string until ECX is 0
MOV DL, [ESI] ; Get the next character in the string
MOV [EDI], DL ; Store the byte at the position of ESI
INC ESI ; Move to next char in source
INC EDI ; INCrement EDI by 1
loop nextByte ; Re-loop to get next byte
MOV byte ptr[EDI], 0h ; Add null-terminator to end of string
; EAX holds a pointer to the start of the dynamically-allocated
; 0-terminated copy of lpSourceString
MOV需要字节ptr
大小说明符,因为[EDI]
内存操作数和0
立即操作数都不会暗示操作的大小。汇编程序不知道您指的是字节、字还是dword存储
我在我的MASM中有这个,但是我使用了一个由于类要求而编写的
String\u length
stdcall方法。当我必须为字符串创建方法而不使用good ole Irvine中的任何内容时,我得到了字符串的长度,将返回的长度(需要为空终止符添加一个额外的+1)增加1,然后在字符串末尾添加0h,指针所在的位置是计数器所在的位置
MOV EAX, SIZEOF lpSourceString + 1 ; Get the string length of string, add 1 to include null-terminator
INVOKE allocMem, EAX ; Allocate memory for a target to copy to
LEA ESI, [lpSourceString] ; put source address in ESI
MOV EDI, EAX ; copy the dest address to another register we can increment
MOV ECX, SIZEOF lpSourceString ; Set up loop counter
我们有绳子的大小。现在我们可以将null终止添加到它。为此,我们需要确保有一个指针指向字符串的末尾。因此,如果我们有一个在EAX中返回字符串的方法,EAX需要指向字符串的开头(因此我们不修改allocMem
,而是增加EDI中的副本)。假设我们将字符放入字符串中:
nextByte: ; Jump label, get the next byte in the string until ECX is 0
MOV DL, [ESI] ; Get the next character in the string
MOV [EDI], DL ; Store the byte at the position of ESI
INC ESI ; Move to next char in source
INC EDI ; INCrement EDI by 1
loop nextByte ; Re-loop to get next byte
MOV byte ptr[EDI], 0h ; Add null-terminator to end of string
; EAX holds a pointer to the start of the dynamically-allocated
; 0-terminated copy of lpSourceString
MOV需要字节ptr
大小说明符,因为[EDI]
内存操作数和0
立即操作数都不会暗示操作的大小。汇编程序不知道您指的是字节、字还是dword存储
我的MASM中有这个,但是我使用了一个
String\u length
stdcall方法,这是我根据类的要求编写的;现在t是说和BYTE PTR[eax+dl],0
指定了一个无效的地址,我感觉我真的走错了方向。在寻址时,不能混合不同大小的寄存器,在这种情况下,需要将偏移量零扩展到整个edx
.Hmm,这样做似乎给了我一个访问违规和程序只是崩溃。。。根据我的调试器,在输入值后立即引发访问冲突,并跳到:和字节PTR[eax+edx],0
,然后在该步骤后崩溃。根据我的调试器,EDX
的值也始终保持0
。对不起,如果我很烦人的话。我真的很困惑。你已经解决了他眼前的问题,但却忽略了他代码不起作用的大局。你正在取消对buff
,edx
应该包含地址。这解决了一个问题;现在t是说和BYTE PTR[eax+dl],0
指定了一个无效的地址,我感觉我真的走错了方向。在寻址时,不能混合不同大小的寄存器,在这种情况下,需要将偏移量零扩展到整个edx
.Hmm,这样做似乎给了我一个访问违规和程序只是崩溃。。。根据我的调试器,在输入值后立即引发访问冲突,并跳到:和字节PTR[eax+edx],0
,然后在该步骤后崩溃。根据我的调试器,EDX
的值也始终保持0
。对不起,如果我很烦人的话。我真的很困惑。你已经解决了他眼前的问题,但却忽略了他的代码为什么不起作用的大局。你正在取消对buf的引用