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
rsito hold the address of the current array element (it’s a perfect fit sincersiis designed as a source index register) - Traverse the array, updating
rsito 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:
- Initialize
rsiwith the array address:lea rsi, [array]loads the base address of your array intorsi—this is where we’ll start tracking element addresses. - Update the format string: Changed from just
%dto%p: %d—%pis theprintfspecifier for printing pointers/addresses in standard hex format (with0xprefix). - Adjust
printfarguments:printfuses registersrdi(format string),rsi(first value),rdx(second value). We pass the address directly viarsi, and the data viardx(by dereferencingrsiwith[rsi]). - Traverse with
rsi: After each print,add rsi, 4shiftsrsito the next element's address (since eachddis 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:
rsistill tracks the current element address from start to finish—we initialize it with the array base and update it withadd rsi,4each loop.- The
addr_to_strhelper converts the address inrsito a human-readable hex string (with0xprefix) 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

