我目前正在尝试将空终结符附加到(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
注册edx BYTE PTR[buff]
的值NULL
。所以我甚至无法开始测试这种尝试将NULL
终止符应用于字符串的方法是否可行。
我的问题是,上面的代码有什么问题(我应该使用不同的寄存器而不是edx吗?)
将{{1}}终止符应用于字符串的最佳方法是什么?
答案 0 :(得分:2)
您无法将字节值移动到双字大小的寄存器中。您需要使用字节大小的寄存器,例如dl
,或者使用movzx
对其进行零扩展。当你使用字节时,我建议你选择第一个选项。
答案 1 :(得分:2)
当我必须不使用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要求使用byte ptr
大小说明符,因为[EDI]
内存操作数和0
立即操作数都不暗示该操作的大小。汇编器不会知道您是要存储字节,字还是dword。
我在MASM中拥有此功能,但是由于类的要求,我使用了我编写的String_length
stdcall方法。
答案 2 :(得分:1)
这很常见,MASM32运行时将此功能作为其运行时的一部分提供。您需要做的就是包含相关代码:
include \masm32\include\masm32rt.inc
然后使用StripLF
函数:
invoke StripLF, addr buff
要解决当前问题(如果您想手动执行此操作),则需要将buff
的地址移至edx
。
mov edx, offset buff