You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

32位汇编代码转64位方案及字符串长度多计数问题咨询

Hey there! Let's tackle your two assembly problems step by step.

1. Converting your 32-bit code to pure 64-bit x86-64 code

x86-64 Linux uses different system calling conventions than 32-bit: we use syscall instead of int 80h, 64-bit registers, and updated system call numbers. Here's how to adjust your code:

  • Replace 32-bit registers with 64-bit equivalents: Swap eax → rax, ebx → rbx, ecx → rcx, edx → rdx (64-bit registers handle 64-bit addresses properly).
  • Update system call numbers:
    • sys_write is now 1 (was 4 in 32-bit)
    • sys_read is now 0 (was 3 in 32-bit)
    • sys_exit is now 60 (was 1 in 32-bit)
  • Use syscall instead of int 80h: This is the standard way to invoke kernel functions in 64-bit mode.
  • Ensure stack alignment: 64-bit Linux requires the stack to be 16-byte aligned before syscall. Adding a simple stack setup at the start fixes this.

Here's the revised 64-bit code:

section .text
global _start
_start:
    ; Align stack to 16 bytes
    push rbp
    mov rbp, rsp

    ; Show prompt message
    mov rdx, 19          ; Number of bytes to write (including newline)
    mov rcx, txt_prompt  ; Address of prompt string
    mov rbx, 1           ; STDOUT file descriptor
    mov rax, 1           ; SYS_WRITE syscall number
    syscall

    ; Read user input
    mov rax, 0           ; SYS_READ syscall number
    mov rbx, 0           ; STDIN file descriptor
    mov rcx, user_input  ; Destination buffer
    mov rdx, 100         ; Max bytes to read
    syscall

    ; Optional: Replace newline with null terminator (fixes length issue too)
    cmp byte [user_input + rax - 1], 0xA
    jne skip_replace
    mov byte [user_input + rax - 1], 0
skip_replace:

    ; Calculate string length
    mov rbx, user_input  ; Base address of input
    mov rax, rbx         ; Current address pointer
strlen_nextchar:
    cmp byte [rax], 0    ; Check for null terminator
    jz strlen_finished   ; Exit loop if found
    inc rax              ; Move to next byte
    jmp strlen_nextchar
strlen_finished:
    sub rax, rbx         ; Compute length (current - base)

    ; Update output string with length (since length <10, we can just add to the digit)
    add byte [txt_output + 33], al

    ; Print result
    mov rdx, 34          ; Length of output string (including newline)
    mov rcx, txt_output  ; Address of output string
    mov rbx, 1           ; STDOUT
    mov rax, 1           ; SYS_WRITE
    syscall

    ; Exit program
    mov rbx, 0           ; Exit code 0
    mov rax, 60          ; SYS_EXIT syscall number
    syscall

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
2. Fixing the extra byte count issue

The problem isn't related to \x10 or \x13—it's about how the read syscall works. When you type input and press enter, Linux adds a newline character (\n, \x0A) to the input buffer. Your original code was looking for a null terminator (0), but the input buffer doesn't have one by default. So your strlen loop counted the newline character (and potentially extra bytes until it hit a random null in memory) as part of the length.

The fix we added above addresses this: right after reading input, we check if the last character is a newline, and replace it with a null terminator. This way, your strlen loop stops at the end of the actual input (excluding the newline), giving you the correct length.

If you want to confirm, try running the original code and entering "test"—it would return 5 instead of 4, because it counts "test\n". The fix makes it return 4 as expected.


内容的提问来源于stack exchange,提问作者ar2015

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 08:29:04