【问题标题】:How to read each char from string NASM assembly 64bit linux如何从字符串 NASM 程序集 64 位 linux 中读取每个字符
【发布时间】:2013-10-18 08:48:54
【问题描述】:

我有一个 64 位 NASM 汇编作业,用于将输入文本的字母大写(所有字母应为小写,句首除外)。我对汇编程序完全陌生,当我阅读这样的文本时,我无法找到如何从字符串中增量读取每个字符:

section .data

prompt      db  "Enter your text: ", 10
length      equ $ - prompt
text        times 255 db 0
textsize    equ $ - text    

section .text
global main
main:
    mov     rax, 1
    mov     rdi, 1
    mov     rsi, prompt
    mov     rdx, length
    syscall         ;print prompt

    mov     rax, 0
    mov     rdi, 0
    mov     rsi, text
    mov     rdx, textsize
    syscall         ;read text input from keyboard




exit:
    mov     rax, 60
    mov     rdi, 0
    syscall

另外,我不确定如何找出文本何时结束,因此我可以知道何时必须退出程序。我应该对文本大小进行一些操作还是有一些显示 EOL 的特殊符号之王?谢谢你的回答。

【问题讨论】:

  • sys_read (syscall 0) 返回在rax IIRC 中读取的字符数。

标签: linux assembly char x86-64 nasm


【解决方案1】:

从 sys_read (syscall rax=0) 返回后,RAX 寄存器应包含实际已读取的字符数。请注意,在 Linux 中,sys_read 将在接受 /n 时返回,即使提供的缓冲区中有更多空间。

然后组织一个从 0 到 RAX 的循环,按照你想要的方式处理每个字符:

        mov    byte ptr [text+rax], 0  ; make the string zero terminated for future use.

        mov    rcx, rax  ; rcx will be the character counter.
        mov    rsi, text ; a pointer to the current character. Start from the beginning.

process_loop:
        mov    al, [rsi]   ; is it correct NASM syntax?

       ; here process al, according to your needs...
       ; .....

       inc    rsi
       dec    rcx
       jnz    process_loop

上面的代码当然可以优化,比如使用字符串指令或者循环指令,但是IMO,这种方式更适合初学者。

【讨论】:

  • +1,但Loop 指令与优化相反。
  • @Johan - 并非总是如此。例如在 80386 上它更快。此外,这取决于“什么优化”——也有大小优化。
  • 正确,386 是 最后一个处理器,loop 的速度更快。 486 于 1989 年推出。
  • @Johan - 您错过了“尺寸优化”这一点。恕我直言,对于现代处理器,只有尺寸优化是合理的。
  • 现代处理器每个周期获取 16 个字节(在 AMD 上是 32 个字节)。循环保存 1 个字节。循环是一个微码指令,需要额外的时间来解码,所以你会失去 +/- 6 uops 空闲(Haswell 上 8 个)。几乎没有优化。更糟糕的是loop 留下了对标志寄存器的错误依赖,因此延迟可能会更长。
猜你喜欢
  • 2016-06-25
  • 2015-12-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-03-19
  • 1970-01-01
相关资源
最近更新 更多