Assembly 以美元结尾的字符串
在我的汇编语言课上,我们的第一个任务是编写一个程序,在DOS中打印一个简单的以美元结尾的字符串。它看起来像这样:Assembly 以美元结尾的字符串,assembly,console,dos,nasm,Assembly,Console,Dos,Nasm,在我的汇编语言课上,我们的第一个任务是编写一个程序,在DOS中打印一个简单的以美元结尾的字符串。它看起来像这样: BITS 32 global _main section .data msg db "Hello, world!", 13, 10, ’$’ section .text _main: mov ah, 9 mov edx, msg int 21h ret 据我所知,$符号用于终止sting,就像C中的null一样。但是如果我想在字符串中放入一个美元符号(比如我想打
BITS 32
global _main
section .data
msg db "Hello, world!", 13, 10, ’$’
section .text
_main:
mov ah, 9
mov edx, msg
int 21h
ret
据我所知,$符号用于终止sting,就像C中的null一样。但是如果我想在字符串中放入一个美元符号(比如我想打印“it costs$30”),我该怎么办?这似乎是一个简单的问题,但我的教授不知道答案,而且我似乎无法通过谷歌搜索找到答案。嗯。您可以编写将转义的
$
考虑在内的程序集,例如\$
?
但是你的
\
也变成了一个特殊的符号,你需要使用\
来打印\
你不能使用DOS的0x09
服务来显示$
符号,你需要使用0x02
。请参阅。尝试使用“$$”、“\044”(八进制)或“\x24”(十六进制)或制作您自己的打印字符串,以使用未记录的INT 29h打印以空结尾的字符串(打印字符为AL)
(假设您使用的是NASM)一种方法是查找打印单个字符的调用。你可以用它打印任何字符。将字符串拆分并打印“it costs”,然后是“$”,最后是“30”。更多的工作,但它完成了任务。您可以使用INT 21H的02服务,而不是09服务 这是样品
mov dl, '$'
mov ah,02
int 21h
我更喜欢使用
write
服务(AH=0x40
):
AH=0x40
是文件句柄;使用值1将数据写入与服务相同的设备(如屏幕)BX
AH=9
是要写入的字节数;数据不是“终止的”(既不是通过NUL也不是通过CX
),因此所有值(从0到255)都可以写入$
指向要写入的数据(在您的示例中为字符串)DS:DX
(就像服务
;如果使用32位DOS扩展:AH=9
,当然)EDX
该服务实际上用于将数据写入文件;但是,通过将
BX
设置为1,它也可以用于将“字符串”写入“输出”。看起来0x40也可以工作:或者,您可以使用0x40,但这需要您指定要写入的字节数(即,它不使用分隔字符串)。@Jason-Heh,比我快一秒钟。:-)请注意,如果使用INT 29h重定向stdout不起作用(例如test.com>output.txt),首选习惯用法是test al,al
,用于根据寄存器设置标志<代码>或al,al速度较慢(在现代x86上),而且从来没有比历史x86上的test
更好。当然,您也可以通过将load和conditional分支放在底部,并使用jmp
进入lodsb
来收紧循环。问题不是在字符串中指定< <代码> $>代码>:键入<代码> dB“这要花费100美元。”完全有效:它将在中间创建一个带有<代码> $< /代码>的字符串。问题是,在汇编语言中,绝对不可能确定这是一个字符串还是两个字符串(例如:“this”
和“成本为100美元。”
)。OP使用的函数使用$
查找字符串的结尾<代码>“$$”不起作用,因为“下一个字符串”可能以$
开头:两个字符串“Hello world.”
和“$100”
将等于:“Hello world.$$100”。
int 21h
/AH=9是DOS“系统调用”。您不需要编写它的实现,只需要调用它。它是ISO Cputs
或FPUT(…,stdout)
的DOS等价物,只是它恼人地使用“$”
而不是0
作为终止符。请参见“反向计算”。如果您的意思是编写自己的字符串输出函数,那么首先就不要使用$
终止符。使其使用$
但以与DOS不兼容的方式使用,其值接近于零。位32
??如何让DOS程序在32位模式下执行,但仍然能够使用int21h
DOS调用?如果机器代码实际以16位模式执行,则解码的16位mov r16,imm16
指令的长度与发出的32位mov r32,imm32
NASM的长度不同,因此msg
地址的高2字节将作为指令进行解码。(可能是0000添加[bx+si],al
,精确地使用这两个字节,让执行达到int 21h
,因此您的代码可能碰巧在16位模式下工作)
mov dl, '$'
mov ah,02
int 21h