在装配中打印字母

时间:2016-08-07 17:09:55

标签: assembly nasm

我开始深入研究装配编程;我使用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中的数据如何被使用?

1 个答案:

答案 0 :(得分:3)

我在您的代码中看到了许多错误:

mov word [output],0x61

这是不正确的,因为您只为output保留了一个字节的空格。请改用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]。或者,如果您将声明从mov edx, [outlength]更改为db,则可以使用dd

现在回答你的问题:

  
      
  1. 我的输出长度为0 - 如何打印?
  2.   

如上所述,它不是0。

  
      
  1. 我只是将换行符移到输出寄存器中 - 那么输出中的数据是如何使用的?
  2.   

因为您将edx设置为"随机"值,您最终可能会打印很多字符(其中一些字符可能不可见)。因此,sys_write最终打印出您在output存储的字符并非不可信。