英文:
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
_sumfunction, as it was not needed for adding two numbers. - 
I used the
resbdirective 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
writesyscall (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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论