【发布时间】:2013-06-24 01:13:04
【问题描述】:
我已经输入DB 13, 10, 'hello world', 0 很长时间了,不知道 13、10 和 0 是干什么用的。
我最近注意到这样做:
PTHIS
DB 'hello world', 0
产生了相同的结果,所以我想知道第一个参数的用途以及以这种方式简单地编写它是否是个好主意。有人可以对此写一个快速解释吗? (我想字符串声明是主题)
【问题讨论】:
我已经输入DB 13, 10, 'hello world', 0 很长时间了,不知道 13、10 和 0 是干什么用的。
我最近注意到这样做:
PTHIS
DB 'hello world', 0
产生了相同的结果,所以我想知道第一个参数的用途以及以这种方式简单地编写它是否是个好主意。有人可以对此写一个快速解释吗? (我想字符串声明是主题)
【问题讨论】:
这是ASCII CR/LF(回车/换行)序列,用于前进到下一行的开头。
历史教训:在旧的电传打字机上,回车正是这样做的,它将马车(打印头)返回到当前行的开头,而换行使纸张前进,以便打印发生在下一行。
您的两个样本不应该产生相同的结果。如果在输出不带CR/LF 的字符串时光标不在行首,Hello world 将显示在某处的中线,即使您确实从行首开始一行,CR/LF 的版本应该先将光标向下移动一行。
末尾的零只是字符串的终止符。一些早期的系统在原始 BIOS 中使用了其他字符,例如 $:
str db "Hello, world$"
这使得将$ 符号输出到控制台相当痛苦:-)
存在终止符是因为您的字符串输出几乎肯定会以字符输出的形式编写,例如伪 asm 代码:
; func: out_str
; input: r1 = address of nul-terminated string
; uses: out_chr
; reguse: r1, r2 (all restored on exit)
; notes: none
out_str push r1 ; save registers
push r2
push r1 ; get address to r2 (need r1 for out_chr)
pop r2
loop: ld r1, (r2) ; get char, finish if nul
cmp r2, 0
jeq done
call out_chr ; output char, advance to next, loop back
incr r2
jmp loop
done: pop r2 ; restore registers and return
pop r1
ret
; func: out_chr
; input: r1 = character to output
; uses: nothing
; reguse: none
; notes: correctly handles control characters
out_chr ; insert function here to output r1 to screen
【讨论】:
13 是 CR ASCII 码 (carriage return) 的十进制值,10 是 LF ASCII 码 (line feed) 的十进制值,0 是字符串的终止零。
这个常量背后的想法是在打印hello world之前更改到下一行。打印子程序需要零终止符才能知道何时结束打印。这类似于null terminating of C strings。
【讨论】:
试试这个
PTHIS
DB 'hello world'
DB 10 ;line feed
DB 13 ;carriage return
DB 'hello world2',0
然后抖动代码
PTHIS
DB 'hello world'
DB 10 ;line feed no carriage return
DB 'hello world2',0
PTHIS
DB 'hello world'
DB 13 ;carriage return no line feed
DB 'hello world2',0
看看会发生什么
【讨论】: