汇编语言 - 什么是临时字符串输入的寄存器
Assembly Language - What is the register of an temp string input
我一直在比较固定字符串和输入字符串。但是很难弄清楚输入寄存器是什么,是 al
、ah
还是什么。我只是一个初学者,这对程序员来说是一种痛苦的语言 lol jk。请帮助我非常感谢:)
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$"
你使用系统调用 0Ah(缓冲输入)http://spike.scu.edu.au/~barry/interrupts.html#ah0a 所以你读取的数据在 temp(缓冲区)
0Ah 从 STDIN 读取 n 个字节到缓冲区
mov bx, OFFSET buffer
将缓冲区地址(此处为 temp)压入 bx,这是 0Ah
所需要的
要固定读取的字节数,您可以使用例如mov byte [bx],15
另请参阅此 http://www.fysnet.net/kbbuffio.htm
mov bl, 'a' ;condition
cmp al, bl
jne aw
比较两个8位值(char),看这个http://x86.renejeschke.de/html/file_module_x86_id_35.html(AL,AH是8位,AX是16位,EAX是32位(扩展AX))
有关 8 位/16 位/32 位/64 位命名约定,请参阅此https://en.wikibooks.org/wiki/X86_Assembly/X86_Architecture#General-purpose_registers_(16-bit_naming_conventions)
这可用于从输入缓冲区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
一起使用所导致的臃肿代码。当使用 assemble-time 常数时,您也可以通过这种方式占用更少的寄存器。
另一个选项(而不是 mov dx, offset msgFalse
)是 add dx, offset msgFalse - msgTrue
,它使立即操作数成为一个小数字(适合使用 imm8 编码的 -128 .. 127 范围)。但是,它不会在 16 位代码中保存任何代码字节,因为 mov dx, imm16
是 3 个字节(每个目标寄存器的专用操作码),而 add dx, imm8
也是三个字节(没有专用操作码)。这将节省 32 位代码中的字节,其中地址为 32 位。
我一直在比较固定字符串和输入字符串。但是很难弄清楚输入寄存器是什么,是 al
、ah
还是什么。我只是一个初学者,这对程序员来说是一种痛苦的语言 lol jk。请帮助我非常感谢:)
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$"
你使用系统调用 0Ah(缓冲输入)http://spike.scu.edu.au/~barry/interrupts.html#ah0a 所以你读取的数据在 temp(缓冲区)
0Ah 从 STDIN 读取 n 个字节到缓冲区
mov bx, OFFSET buffer
将缓冲区地址(此处为 temp)压入 bx,这是 0Ah
要固定读取的字节数,您可以使用例如mov byte [bx],15
另请参阅此 http://www.fysnet.net/kbbuffio.htm
mov bl, 'a' ;condition
cmp al, bl
jne aw
比较两个8位值(char),看这个http://x86.renejeschke.de/html/file_module_x86_id_35.html(AL,AH是8位,AX是16位,EAX是32位(扩展AX))
有关 8 位/16 位/32 位/64 位命名约定,请参阅此https://en.wikibooks.org/wiki/X86_Assembly/X86_Architecture#General-purpose_registers_(16-bit_naming_conventions)
这可用于从输入缓冲区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
一起使用所导致的臃肿代码。当使用 assemble-time 常数时,您也可以通过这种方式占用更少的寄存器。
另一个选项(而不是 mov dx, offset msgFalse
)是 add dx, offset msgFalse - msgTrue
,它使立即操作数成为一个小数字(适合使用 imm8 编码的 -128 .. 127 范围)。但是,它不会在 16 位代码中保存任何代码字节,因为 mov dx, imm16
是 3 个字节(每个目标寄存器的专用操作码),而 add dx, imm8
也是三个字节(没有专用操作码)。这将节省 32 位代码中的字节,其中地址为 32 位。