英文:
x64 NASM Assembly print a single character returned from the function
问题
I noticed some issues in your NASM x64 Assembly code that may be causing the problem with not displaying the expected result. Here's the corrected code:
; NASM x64 Assembly program to add two numbers and print the result
section .data
message db "The sum is: ", 0 ; Null-terminated string
section .bss
result resb 1 ; Reserve space for a single byte (to store the result)
section .text
global _start
_start:
; Display the message
mov rax, 0x1 ; Syscall number for sys_write (1)
mov rdi, 0x1 ; File descriptor for STDOUT (1)
mov rsi, message ; Pointer to the message
mov rdx, 13 ; Message length
syscall
; Calculate the sum (4 + 5)
mov rax, 4
add rax, 5
mov [result], al ; Store the result in the result variable
; Display the result
mov rax, 0x1 ; Syscall number for sys_write (1)
mov rdi, 0x1 ; File descriptor for STDOUT (1)
mov rsi, result ; Pointer to the result
mov rdx, 1 ; Result length (1 byte)
syscall
; Exit the program
mov rax, 60 ; Syscall number for sys_exit (60)
xor rdi, rdi ; Exit status (0)
syscall
In this corrected code:
-
I removed unnecessary procedure calls and the
_sum
function, as it was not needed for adding two numbers. -
I used the
resb
directive to reserve space for a single byte to store the result, and then I stored the result in that memory location usingmov [result], al
. -
I ensured that the message string is null-terminated by adding a null character (0) at the end of the string.
-
I made sure to set the correct message length when calling the
write
syscall (13 characters). -
Finally, I used the correct syscall number (60) and exit status (0) when exiting the program.
Please try assembling and running this corrected code, and it should display the expected result: "The sum is: 9".
英文:
I was writing a simple NASM x64 Assembly program that adds two single-digit numbers(4
and 5
respectively) and print it on the screen. However, I wanted to use a procedure call(function). So I designed the the program in C language first.
#include <stdio.h>
int sum(int x, int y) {
int result = x + y;
return result;
}
int main(void) {
int x = 4;
int y = 5;
int result = sum(x, y);
printf("The sum is: %d\n", result);
return 0;
}
And I rewrote the program in NASM x64 Assembly program like below. The expected output from the program was The sum is: 9
. However, I only could see the result except for the calculation result, just The sum is:
.
; Nasm 2.15.05 (on Linux x64)
STDOUT equ 0x01 ; for RDI (file descriptor)
WRITE equ 0x01 ; for RAX (for syscall itself)
section .data
message db "The sum is: "
messageLength equ $ - message
section .text
global _start
_start:
mov rax, WRITE
mov rdi, STDOUT
mov rsi, message
mov rdx, messageLength
syscall
mov rdi, 0x4
mov rsi, 0x5
call _sum
mov rcx, rax ; The result of the _sum (stored in RAX register)
mov rax, WRITE
mov rdi, STDOUT
mov rsi, rcx
mov rdx, 0x01
syscall
; exit
mov rax, 0x3C
mov rdi, 0x00
syscall
_sum:
mov rax, rdi
add rax, rsi
add rax, '0' ; To make it printable ASCII
ret ; Result: 0x39 (A single character '9' in ASCII)
(My environment is WSL Ubuntu 22.04 on Windows 11, Intel i9-13900H CPU)
knightchaser@3rdfr13nds:~/assembly$ ./procedures_x64
The sum is: knightchaser@3rdfr13nds:~/assembly$
With GDB(GNU Debugger), I checked the calculation of _sum
was successful so 0x39
(9
in ASCII character) was stored in RAX
register and the program doesn't show any explicit errors like segmentation fault
.
I used the following commands to make the executable program.
nasm -f elf64 -o procedures_x64.o procedures_x64.asm
ld -o procedures_x64 procedures_x64.o
But I can't see the result. Are there wrong points in my Assembly code? Thanks in advance!
答案1
得分: 2
为了打印您的字符,您需要执行以下操作:
mov rcx, rax ; _sum 的结果(存储在 RAX 寄存器中)
;...
mov rsi, rcx
问题在于rax
中返回的值是一个单个字符,并且您将这个单个字符的值移动到rsi
中。write
系统调用期望rsi
中的值是指向字符的指针,而不是实际的字符值本身。
您需要将字符存储在内存中,然后将指向该内存的指针传递给write
函数。
如果您在C中编写了一个精确等效的代码,那么当您需要使用指针操作符&
来打印返回的字符(或使用字符数组)时,这将非常明显。我强烈建议您先使正确的C程序运行起来,包括系统调用、适当的sum
函数以及从int
到字符串的转换,并将其用作汇编程序的蓝图。
英文:
To print your character you do
mov rcx, rax ; The result of the _sum (stored in RAX register)
;...
mov rsi, rcx
The problem is that the value returned in rax
is a single character, and you move that single character value into rsi
. The write
system call expects the value in rsi
to be a pointer to a character, not the actual character value itself.
You need to store the character in memory, and then pass a pointer to that memory to the write
function.
If you wrote an exact equivalent in C it would be very obvious when you have to use the pointer-to operator &
to print the returned character (or used a character array). I highly recommend that you get the proper C Program working, with the system calls and a proper sum
function and conversion from int
to a string, and use that as the blueprint for the assembly program.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论