如何在Linux x86 NASM中打印字符?

时间:2014-01-29 11:13:02

标签: linux assembly x86 nasm

我正在尝试使用 NASM 打印单个字符或数字,目标是x86 GNU / Linux架构。

这是我正在使用的代码:

section .text
    global _start

_start:

    ; Linux printing preparation
    mov eax,4            
    mov ebx,1       

    ; Print 'A' character 
    mov ecx,'A'     ; ecx should contain the value to print
    mov edx,1       ; edx should contain how many characters to print
    int 80h

    ; System exit
    mov eax,1            
    mov ebx,0            
    int 80h

然而,运行此代码不会打印任何内容。我做错了什么?

2 个答案:

答案 0 :(得分:8)

ecx应包含指向char缓冲区开头的指针。所以你必须把你的缓冲区放在内存中。您可以执行以下操作:

; Print 'A' character 
mov   eax, 4      ; __NR_write from asm/unistd_32.h (32-bit int 0x80 ABI)
mov   ebx, 1      ; stdout fileno

push  'A'
mov   ecx, esp    ; esp now points to your char
mov   edx, 1      ; edx should contain how many characters to print
int   80h         ; sys_write(1, "A", 1)

; return value in EAX = 1 (byte written), or error (-errno)

add   esp, 4      ; restore esp if necessary

如果可以覆盖堆叠中的任何内容,您可以mov byte [esp], 'A'或其他任何地址。

或者您可以在section .rodata中使用字符数组,而不是动态存储。

答案 1 :(得分:1)

您正在执行的系统调用期望ecx在内存中包含一个地址。这可以是任意文字地址(即,在您的代码中,"A"转换为地址041h),堆栈上的地址或程序中标签定义的地址。

下面是在内存中定义一个字节并将其写入终端的标准输出流的示例:

    section .rodata  ; This section contains read-only data
buffer:    db 'A'    ; Define our single character in memory

    section .text
    global start
_start:
    ; Prints the letter 'A', then exits

    mov eax, 4      ; sys_write()
    mov ebx, 1      ; ... to STDOUT
    mov ecx, buffer ; ... using the following memory address
    mov edx, 1      ; ... and only print one character
    int 80h         ; SYSCALL

    mov eax, 1      ; Return to system
    mov ebx, 0      ; Exit zero, success
    int 80h         ; SYSCALL