Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/assembly/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Assembly 我的汇编代码为字符串长度额外计算一个字节_Assembly_64 Bit_X86 64_Nasm - Fatal编程技术网

Assembly 我的汇编代码为字符串长度额外计算一个字节

Assembly 我的汇编代码为字符串长度额外计算一个字节,assembly,64-bit,x86-64,nasm,Assembly,64 Bit,X86 64,Nasm,我编写了以下代码来阅读文本,计算长度并报告它。为了保持代码简单,我假设字符串的长度小于10个字符 我用于构建的代码是 nasm -f elf64 strlen.asm && ld strlen.o -o strlen && ./strlen 我有两个问题: 此代码编译为64位,而代码本身为32位。我应该应用什么更改使代码也变成64位 为什么应用程序总是额外报告一个字节的长度?理论上,它不计算空终止。给定的文本是否包括\x10或\x13 section.text

我编写了以下代码来阅读文本,计算长度并报告它。为了保持代码简单,我假设字符串的长度小于10个字符

我用于构建的代码是

nasm -f elf64 strlen.asm && ld strlen.o -o strlen && ./strlen
我有两个问题:

  • 此代码编译为64位,而代码本身为32位。我应该应用什么更改使代码也变成64位
  • 为什么应用程序总是额外报告一个字节的长度?理论上,它不计算空终止。给定的文本是否包括
    \x10
    \x13
    section.text
    全球启动
    _开始:
    ; 显示提示信息
    mov-edx,19;要写入的字节数-每个字母一个加上0Ah(换行字符)
    mov ecx,txt_提示符;将消息字符串的内存地址移到ecx中
    mov-ebx,1;写入标准输出文件
    mov-eax,4;调用系统写入(内核操作码4)
    int 80h
    ; 读取用户输入
    mov-eax,3;将用户输入读入str
    mov-ebx,0|
    
    mov ecx,用户输入;|是,
    read()
    也返回行尾字符。您可以使用调试器看到这一点。注意它不是
    \x10
    ,因为它是十六进制。十进制是10。对于64位,使用64位系统调用和寻址模式。和
    默认rel
    。有一些链接。请注意,将其构建为64位将使其成为64位。只是它碰巧也是一个有效的64位程序,当作为Linux非饼图可执行文件(虚拟地址空间低32位中的静态地址)链接时,它正好工作。如果您使用了
    push ebx
    或其他什么,它将不会进行汇编,因为这不是合法的64位模式指令。如果您使用的是
    mov esp,ebp
    /ret.@Jester,谢谢。我可以在Ubuntu上使用哪个调试器?常用的调试器是
    gdb
    ,如果你喜欢的话,它有前端。@Jester,
    nasm
    gdb
    配合得好吗?是的,
    read()
    也返回行尾字符。您可以使用调试器看到这一点。注意它不是
    \x10
    ,因为它是十六进制。十进制是10。对于64位,使用64位系统调用和寻址模式。和
    默认rel
    。有一些链接。请注意,将其构建为64位将使其成为64位。只是它碰巧也是一个有效的64位程序,当作为Linux非饼图可执行文件(虚拟地址空间低32位中的静态地址)链接时,它正好工作。如果您使用了
    push ebx
    或其他什么,它将不会进行汇编,因为这不是合法的64位模式指令。如果使用
    mov esp,ebp
    /ret.@Jester,谢谢。我可以在Ubuntu上使用哪个调试器?常用的调试器是
    gdb
    ,如果你喜欢的话,它有前端。@Jester,
    nasm
    gdb
    配合得好吗?
    section .text
    global _start
    
    _start:
    
    ; show prompt message
        mov     edx, 19     ; number of bytes to write - one for each letter plus 0Ah (line feed character)
        mov     ecx, txt_prompt    ; move the memory address of our message string into ecx
        mov     ebx, 1      ; write to the STDOUT file
        mov     eax, 4      ; invoke SYS_WRITE (kernel opcode 4)
        int     80h
    
    ; read the user input
        mov eax, 3          ; Read user input into str
        mov ebx, 0          ; |
        mov ecx, user_input        ; | <- destination
        mov edx, 100        ; | <- length
        int 80h             ; \
    
    ; calculate the length
    
        mov     ebx, user_input        ; move the address of our message string into EBX
        mov     eax, ebx        ; move the address in EBX into EAX as well (Both now point to the same segment in memory)
    
    strlen_nextchar:
        cmp     byte [eax], 0   ; compare the byte pointed to by EAX at this address against zero (Zero is an end of string delimiter)
        jz      strlen_finished        ; jump (if the zero flagged has been set) to the point in the code labeled 'finished'
        inc     eax             ; increment the address in EAX by one byte (if the zero flagged has NOT been set)
        jmp     strlen_nextchar        ; jump to the point in the code labeled 'strlen_nextchar'
    
    strlen_finished:
        sub     eax, ebx        ; subtract the address in EBX from the address in EAX
        add     byte [txt_output+33], al
    
    ; show output message
        mov     edx, 34     ; number of bytes to write - one for each letter plus 0Ah (line feed character)
        mov     ecx, txt_output    ; move the memory address of our message string into ecx
        mov     ebx, 1      ; write to the STDOUT file
        mov     eax, 4      ; invoke SYS_WRITE (kernel opcode 4)
        int     80h
    
    ; exit code
        mov     ebx, 0
        mov     eax, 1
        int     80h
    
    section .data
    txt_prompt:   db      'Enter your message:', 0Ah
    txt_output:   db      'The string length is calculated: 0', 0Ah
    
    section .bss
    user_input: resb 100