在汇编中打印字母表

Printing the Alphabet in Assembly

我开始钻研汇编编程;我使用 NASM 作为 64 位 Debian 系统的汇编器。为了弄湿自己,我从一个基本项目开始——打印小写字母表,一次一个字母,每行一个字母。

从技术上讲,我成功实现了这个目标 - 但我不确定如何实现。这是我的程序:

section .data
    newline: db 0x0A
    outlength: db 0x00

section .bss ; variables
    output:     resb 1

section .text ;main function
    global _start


_start:
    mov word [output],0x61

_loop:
    call _write
    mov eax, [output]
    inc eax
    mov [output],eax
    cmp eax, 0x7B
    jne _loop;

    mov eax,1
    mov ebx,0
    int 80h

_write:
    mov eax,4
    mov ebx,1
    mov edx,outlength
    mov ecx,newline
    int 80h
    ret

该程序产生以下输出:

a
b
c
d
e
f
g
h
i
j
k
l
m
n
o
p
q
r
s
t
u
v
w
x
y
z

这里很难显示,但是在第一行之前有一个额外的换行符,我的 bash 提示符紧跟在 z 字符之后(在同一行)。这个输出是如何产生的? output 既是要写入的字符,也是循环的计数器; newline 是包含换行符本身的保留字节。有两个未解决的问题我无法弄清楚:

1.我的输出长度是 0 - 怎么打印出来的?

2。我只将 newline 移动到输出寄存器中 - 那么 output 中的数据如何使用?

我发现你的代码中有很多错误:

mov word [output],0x61

这是不正确的,因为您只为 output 保留了 space 的一个字节。请改用 mov byte [output],0x61


mov eax, [output]
inc eax
mov [output],eax

出于同样的原因,这是不正确的。 output 是一个字节,而不是 dword。您可以简单地使用 inc byte [output](然后是 cmp byte [output],0x7B)。


mov edx,outlength

这会将 outlength 的地址放在 edx 中,而不是它的值(参见 NASM Requires Square Brackets For Memory References)。
你想要movzx edx, byte [outlength]。或者,如果将声明从 db 更改为 dd

,则可以使用 mov edx, [outlength]

现在回答你的问题:

  1. My output length is 0 - how is anything ever being printed?

如上所述,它不是 0。

  1. I'm only ever moving newline into the output register - so how is the data in output being used?

由于您将 edx 设置为 "random" 值,您最终可能会打印大量字符(其中一些可能不可见)。因此,sys_write 最终打印您存储在 output 的字符并非不合理。