繁体   English   中英

Windows(x86)程序集将空终止符附加到输入的字符串

[英]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).

所以我假设我不能MOVBYTE 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM