在缓冲区内将字符串移动到末尾 - 汇编语言

3
我正在尝试接收一个字符串,然后查看字符串的最后一个值是否为EOL(行尾)字符。我想通过读取的字符串长度并将其添加到缓冲区地址来找到最后一个元素。但这种方法似乎不起作用。
编辑:很抱歉我没有包含更多信息。变量定义如下:
  %define BUFLEN 256

  SECTION .bss                    ; uninitialized data section
    buf:    resb BUFLEN                     ; buffer for read
    newstr: resb BUFLEN                     ; converted string
    rlen:   resb 4   

然后,调用 dos 中断 来接受用户输入的字符串,代码如下:
    ; read user input
    ;
    mov     eax, SYSCALL_READ       ; read function
    mov     ebx, STDIN              ; Arg 1: file descriptor
    mov     ecx, buf                ; Arg 2: address of buffer
    mov     edx, BUFLEN             ; Arg 3: buffer length
    int     080h

然后我们进入循环:

  test_endl:
    mov     ecx, [rlen]
    mov     esi, buf
    add     esi, ecx                ; i want to move 'rlen' bytes into buf
    mov     al, [esi]               ; to see what the last element is
    cmp     al, 10                  ; compare it to EOL
    jnz     L1_init
    dec     ecx                     ; and then decrease 'rlen' if it is an EOL
    mov     [rlen], ecx\

我正在使用NASM编译和为i386机器编写代码。


我猜你正在使用nasm?你的问题没有明确说明。但如果你在问题中包含了定义rlenbuf的代码部分,那将会很有帮助。我敢打赌你在定义rlen时出现了问题。 - Michael Petch
1
他已经包含了最小的示例,投票关闭这个问题是一个糟糕的决定! - peterh
@peterh,考虑到目前的情况,我认为你是错的。事实上,这位发布者现在已经修改了他最初的问题(我现在才知道)。当我写下关闭时,OP没有定义变量声明,因此它并不完整。变量的大小(最初未知)可能会导致 "mov ecx,[rlen]" 的问题。既然OP实际上修改了他的问题,我愿意撤回关闭投票。请查看编辑历史记录,您将看到它在一天后变得完整。 - Michael Petch
2个回答

4
将字符串的长度加到缓冲区地址上可以访问字符串后面的字节。
根据您所说:
- 您想查看字符串中的最后一个值是否为EOL字符
- 如果是EOL,则您的目标是减少'rlen'
我得出结论,您认为可能的EOL字符是由其长度'rlen'定义的字符串的一部分。如果不是这样,那么(*)就没有意义。
使用mov al,[esi-1]来查看最后一个元素是什么!
test_endl:
  mov     ecx, [rlen]
  mov     esi, buf
  add     esi, ecx         ; i want to move 'rlen' bytes into buf
  mov     al, [esi-1]      ; to see what the last element is
  cmp     al, 10           ; compare it to EOL
  jnz     L1_init
  dec     ecx              ; and then decrease 'rlen' if it is an EOL
  mov     [rlen], ecx

你是否考虑到 rlen 可能被定义为字节或者字,而且在你的回答中有没有考虑到这一点?问题是,如果没有更多的信息,你所建议的可能不是所有的错误。 - Michael Petch
1
我们必须相信操作者。如果他/她写了 mov ecx,[rlen],我相信他/她知道它是一个 dword。 - Fifoernik
你会惊讶地发现,我在 Stack Overflow 上看到过很多次这个问题最终成为一个大问题。事实是,这是一个措辞不当的问题,因为它不是 MCVE。我不会对那些可能刚接触汇编语言的人做出这样的假设。 - Michael Petch
这是正确的答案,适用于我的应用程序。感谢您的帮助。我还想出了一个另外的,更长的解决方案,我会发帖分享。 - landesko
我已经给这个答案点赞,因为它现在与给定的更新问题相匹配。 - Michael Petch

0

这是一种更加迂回的方式(字面意思),以到达字符串的末尾。我根据计数器rlen的大小循环遍历字符串中的所有字符。然后,一旦循环完成,我进行比较并根据需要递减rlen。

test_loop:
    mov     al, [esi]               ; get a character
    inc     esi                     ; update source pointer
    dec     ecx                     ; update char count
    jnz     test_loop               ; loop to top if more chars
    cmp     al, 10                  ; comparison
    jne     L1_init                 ; if not EOL jump to L1_init
    mov     ecx, [rlen]             ; decrease the size of rlen if necessary
    dec     ecx
    mov     [rlen], ecx

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接