Assembly 汇编语言-什么是临时字符串输入的寄存器
我一直在比较固定字符串和输入字符串。但是很难弄清楚输入的寄存器是什么,是al,啊还是别的什么。我只是一个初学者,对于程序员来说,这是一门痛苦的语言。请帮忙我真的很感激谢谢:Assembly 汇编语言-什么是临时字符串输入的寄存器,assembly,emulation,emu8086,Assembly,Emulation,Emu8086,我一直在比较固定字符串和输入字符串。但是很难弄清楚输入的寄存器是什么,是al,啊还是别的什么。我只是一个初学者,对于程序员来说,这是一门痛苦的语言。请帮忙我真的很感激谢谢: mov dx, offset temp ;string input mov ah, 0ah int 21h mov bl, "a" ;condition cmp al, bl jne aw mov dx, offset msgTrue
mov dx, offset temp ;string input
mov ah, 0ah
int 21h
mov bl, "a" ;condition
cmp al, bl
jne aw
mov dx, offset msgTrue ;true
mov ah, 09
int 21h
aw: ;false
mov dx, offset msgFalse
mov ah, 09
int 21h
ret
msg db 10, 13, " * ************************************ *****$"
msg1 db 10, 13, " *** * Ticketing System * ***$"
msg2 db 10, 13, " ***** ************************************ *$"
msg3 db 10, 13, " ==========================$"
msg4 db 10, 13, " = (a)Land =$"
msg5 db 10, 13, " = (b)Water =$"
msg6 db 10, 13, " = (c)Air =$"
msg7 db 10, 13, " ==========================$"
msg8 db 10, 13, " Choose Travel Type: $"
temp db 2, 0, 3 dup("$")
msgTrue db 10, 13, " You selected Land$"
msgFalse db 10, 13, " Invalid Input$"
您使用syscall 0Ah缓冲输入,以便读取的数据位于临时缓冲区中 0Ah将n个字节从STDIN读入缓冲区 mov bx,OFFSET buffer将缓冲区的地址推到这里,temp在bx中,这是0Ah所需要的 要固定读取的字节数,可以使用例如mov字节[bx],15 也见此 比较两个8位值char,参见此AL,AH为8位,AX为16位,EAX为32位扩展AX 有关8-/16-/32-/64位命名约定,请参见此 这可用于从输入缓冲区temp读取读取输入字节并进行比较:
val DB 'a'
mov al, val ;condition
mov bx, OFFSET temp ; address of temp in bx: bx is a pointer to first byte in temp now
;alternatively you can use lea bx, [temp]
add bx, 2 ; structure of input buffer (here temp) http://spike.scu.edu.au/~barry/interrupts.html#dosbuf
mov dl, byte [bx] ; writes the byte [bx] points to in dl - [bx] dereferences bx - the byte command treats bx as a char* - see https://www.cs.uaf.edu/2006/fall/cs301/lecture/10_02_pointer.html
cmp al, dl
jne aw
结果在内存中,您要求系统调用将其放入内存。见拉尔夫的回答 检查输入,如下所示:
mov dx, offset temp ; input buffer
mov ah, 0ah ; buffered input syscall
int 21h
; select one of two messages to print
mov dx, offset msgTrue
cmp byte ptr [temp+2], 'a' ; compare the first byte of user input
je .true
mov dx, offset msgFalse ; conditionally skip this instruction
.true:
mov ah, 09 ; print string syscall
int 21h
请注意,mov ah/int 0x21代码仅出现一次,分支仅跳过一条指令。您可以在现代CPU上使用cmov进行编码,但令人恼火的是,cmov没有直接的源代码编码
请参阅Ralf回答中的评论,以了解对臃肿代码的批评,这种代码不仅仅是由于在cmp中使用直接操作数造成的。在使用汇编时间常数时,也可以通过这种方式占用更少的寄存器
另一个替代mov dx、offset msgFalse的选项是add dx、offset msgFalse-msgTrue,这使立即数操作数成为一个适合-128内的小数字。。127使用imm8编码的范围。但它不会在16位代码中保存任何代码字节,因为mov dx、imm16是每个dest寄存器的3字节专用操作码,加上dx,imm8也是3字节无专用操作码。这将节省32位代码中的字节,其中地址为32位。为什么不指出cmp al,“a”将更简单?当一个直系亲属的工作方式相同时,不需要捆绑bl。甚至有一个特殊的编码cmp立即与al,所以它只是一个2字节的指令,即使即时。还有,你认为mov bl‘a’有什么不对?大多数汇编器允许您在整数常量出现的任何位置使用字符常量。多字符常量生成多字节整数。与cmp字节[temp],'a'/jne相比,仍然非常笨拙。还要注意,16位有效地址不能使用dx作为基或索引,只能使用BX/BP+SI/DI。这只是16位代码糟糕透顶、浪费学习时间的众多原因之一。这些限制在其他模式中不存在。我不打算这样做,但我不能让低效的代码单独存在感谢您整理输入缓冲区的格式。我不是一个DOS的家伙,我对学习DOS系统调用没有兴趣,只是想帮助别人。哦,顺便说一句,偏移温度+3与偏移温度+3不同。您正在添加ascii编码>。您是对的,它是+2。首先读取时,它认为缓冲区中的字节02也具有“管理功能”,然后开始读取用户字节…代码中的其他问题:[dx]不是有效地址。你的代码无法汇编。使用bx、bp、si或di。e、 g.mov si,偏移温度+2/cmp字节ptr[si],“a”。32位有效地址是相同的,只是没有限制,并且您可以缩放索引。请参阅我先前评论中的链接,了解我在32位EAs上所做的写入操作。如果您愿意,您可以将指令浪费在regs中,但是:请注意,您不需要标记msg1/msg2等。您可以只使用未标记的db行。
mov dx, offset temp ; input buffer
mov ah, 0ah ; buffered input syscall
int 21h
; select one of two messages to print
mov dx, offset msgTrue
cmp byte ptr [temp+2], 'a' ; compare the first byte of user input
je .true
mov dx, offset msgFalse ; conditionally skip this instruction
.true:
mov ah, 09 ; print string syscall
int 21h