在汇编中打印字母表
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]
现在回答你的问题:
- My output length is 0 - how is anything ever being printed?
如上所述,它不是 0。
- I'm only ever moving newline into the output register - so how is the data in output being used?
由于您将 edx
设置为 "random" 值,您最终可能会打印大量字符(其中一些可能不可见)。因此,sys_write
最终打印您存储在 output
的字符并非不合理。
我开始钻研汇编编程;我使用 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]
现在回答你的问题:
- My output length is 0 - how is anything ever being printed?
如上所述,它不是 0。
- I'm only ever moving newline into the output register - so how is the data in output being used?
由于您将 edx
设置为 "random" 值,您最终可能会打印大量字符(其中一些可能不可见)。因此,sys_write
最终打印您存储在 output
的字符并非不合理。