x64 NASM Assembly 打印从函数返回的单个字符。

huangapple go评论63阅读模式
英文:

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:

  1. I removed unnecessary procedure calls and the _sum function, as it was not needed for adding two numbers.

  2. 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 using mov [result], al.

  3. I ensured that the message string is null-terminated by adding a null character (0) at the end of the string.

  4. I made sure to set the correct message length when calling the write syscall (13 characters).

  5. 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.

huangapple
  • 本文由 发表于 2023年7月10日 13:48:16
  • 转载请务必保留本文链接:https://go.coder-hub.com/76650936.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定