[英]Windows (x86) Assembly Append Null Terminator To Inputted String
我目前正在尝试将空终止符附加到(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 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]
上组装,并给我一个错误:
error: Invalid combination of opcode and operands (or wrong CPU setting).
所以我假设我不能MOV
值BYTE PTR[buff]
到寄存器EDX。 因此,我什至无法开始测试这种尝试将NULL
终止符应用于字符串的方法是否还能工作。
我的问题是,上述代码有什么问题(我应该使用其他寄存器代替edx吗?)
将NULL
终止符应用于字符串的最佳方法是什么?
您不能将字节值移到双字大小的寄存器中。 您要么需要使用字节大小的寄存器(例如dl
,要么使用movzx
对其进行零扩展。 在处理字节时,建议您选择第一个选项。
当我不得不为字符串创建方法而又不使用ole Irvine的任何东西时,我得到了字符串的长度,将返回的长度增加了(您需要为null终止符添加一个额外的+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要求使用byte ptr
大小说明符,因为[EDI]
内存操作数和0
立即操作数均不表示该操作的大小。 汇编器不会知道您是要存储字节,字还是dword。
我在MASM中有此功能,但是由于类的要求,我使用了我编写的String_length
stdcall方法。
这非常普遍,以致MASM32运行时在其运行时提供此功能。 您所需要做的就是包含相关代码:
include \masm32\include\masm32rt.inc
然后按以下方式使用StripLF
函数:
invoke StripLF, addr buff
要解决当前问题(如果要手动解决),则需要将buff
的地址移到edx
。
mov edx, offset buff
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.