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

时间:2012-10-05 14:05:20

标签: 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            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}}终止符应用于字符串的最佳方法是什么?

3 个答案:

答案 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