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

64位NASM中如何同时显示数据与地址?实操代码修改咨询

Hey there! Let's break down how to solve this problem—showing each array element's address alongside its data in the address: data format, while using the rsi register to track addresses. I'll walk you through key modifications and share working code examples based on typical x86-64 assembly setups.

Core Approach

The main goals are straightforward:

  • Use rsi to hold the address of the current array element (it’s a perfect fit since rsi is designed as a source index register)
  • Traverse the array, updating rsi to point to the next element each iteration
  • Output both the address (stored in rsi) and the data at that address in your desired format

Example 1: Using C Library (printf) for Simplicity

If you’re linking against the C standard library (e.g., compiling with gcc), this is the easiest route—printf handles formatting addresses and numbers for you automatically.

Modified Code

section .data
    ; Your array of double-word integers
    array dd 10, 20, 30, 40, 50
    ; Calculate number of elements (each `dd` is 4 bytes)
    len equ ($ - array) / 4
    ; Format string: %p outputs address (hex with 0x prefix), matches your desired format
    fmt db "%p: %d", 10, 0

section .text
    extern printf
    global main
main:
    mov rcx, len          ; Set loop counter to array length
    lea rsi, [array]      ; Initialize rsi to point to the START of the array (first element's address)

loop_start:
    mov rdi, fmt          ; 1st printf argument: format string
    mov rdx, [rsi]        ; 3rd printf argument: data at the current address (dereference rsi)
    call printf           ; Print "address: data" — rsi is automatically the 2nd argument!
    
    add rsi, 4            ; Move rsi to the next element's address (4 bytes per `dd`)
    dec rcx               ; Decrement loop counter
    jnz loop_start        ; Repeat until all elements are processed

    mov rax, 0            ; Return 0 to indicate success
    ret

Key Modifications Explained:

  1. Initialize rsi with the array address: lea rsi, [array] loads the base address of your array into rsi—this is where we’ll start tracking element addresses.
  2. Update the format string: Changed from just %d to %p: %d—%p is the printf specifier for printing pointers/addresses in standard hex format (with 0x prefix).
  3. Adjust printf arguments: printf uses registers rdi (format string), rsi (first value), rdx (second value). We pass the address directly via rsi, and the data via rdx (by dereferencing rsi with [rsi]).
  4. Traverse with rsi: After each print, add rsi, 4 shifts rsi to the next element's address (since each dd is 4 bytes long).

Example 2: Pure Assembly (No C Library)

If you need to use raw Linux system calls, you’ll need to manually convert addresses and numbers to strings. Here’s how to do it while still using rsi for address tracking:

section .data
    array dd 10, 20, 30, 40, 50
    len equ ($ - array) / 4
    colon db ": "
    colon_len equ $ - colon
    newline db 10

section .bss
    addr_buf resb 18  ; Buffer to store address string (0x + 16 hex digits + null terminator)
    num_buf resb 10   ; Buffer to store data string

section .text
    global _start
_start:
    mov rcx, len
    lea rsi, [array]  ; Initialize rsi to array start address

loop:
    ; Step 1: Convert address in rsi to string
    mov rdi, addr_buf
    call addr_to_str

    ; Print address string
    mov rax, 1
    mov rdi, 1
    mov rsi, addr_buf
    mov rdx, 18
    syscall

    ; Print ": "
    mov rax, 1
    mov rdi, 1
    mov rsi, colon
    mov rdx, colon_len
    syscall

    ; Step 2: Convert data at rsi to string
    mov eax, [rsi]
    mov rdi, num_buf
    call int_to_str

    ; Print data string
    mov rax, 1
    mov rdi, 1
    mov rsi, num_buf
    mov rdx, 10
    syscall

    ; Print newline
    mov rax, 1
    mov rdi, 1
    mov rsi, newline
    mov rdx, 1
    syscall

    ; Update address and counter
    add rsi, 4
    dec rcx
    jnz loop

    ; Exit program
    mov rax, 60
    mov rdi, 0
    syscall

; Helper: Convert 64-bit address in rsi to hex string (stored in rdi)
addr_to_str:
    mov byte [rdi], '0'
    mov byte [rdi+1], 'x'
    mov rcx, 16
    mov rbx, rsi

next_digit:
    mov rax, rbx
    and rax, 0xF
    cmp rax, 9
    jbe digit_num
    add rax, 'A'-10
    jmp digit_store
digit_num:
    add rax, '0'
digit_store:
    mov byte [rdi+1+rcx], al
    shr rbx, 4
    dec rcx
    jnz next_digit
    mov byte [rdi+18], 0
    ret

; Helper: Convert 32-bit integer in eax to decimal string (stored in rdi)
int_to_str:
    mov rcx, 0
    mov rbx, 10
next_num:
    xor rdx, rdx
    div rbx
    add dl, '0'
    mov byte [rdi+rcx], dl
    inc rcx
    cmp eax, 0
    jnz next_num

    ; Reverse the string (since we built it backwards)
    mov rsi, rdi
    mov rdx, rsi
    add rdx, rcx-1
reverse:
    cmp rsi, rdx
    jge reverse_done
    mov al, [rsi]
    mov bl, [rdx]
    mov [rsi], bl
    mov [rdx], al
    inc rsi
    dec rdx
    jmp reverse
reverse_done:
    mov byte [rdi+rcx], 0
    ret

Key Notes for Pure Assembly:

  • rsi still tracks the current element address from start to finish—we initialize it with the array base and update it with add rsi,4 each loop.
  • The addr_to_str helper converts the address in rsi to a human-readable hex string (with 0x prefix) for output.
  • We print the address string, followed by : , then the data string, then a newline to match your desired format.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 04:36:46