我有一个练习,我对此有一些疑问。我有一本书解释它,但我不明白他的意思。我在互联网上看,但我找不到我的一些问题或同样的我不能了解。练习是指用户收到一条消息,之后将用拉丁字符给键盘,并且在控制之后将保存在内存的一个区域上只有大写字母,小拉丁字符和空(空格)和句号(。)。区域将被保存为缓冲区并将为40字节。如果按“ENTER”或已完成40个字符,则启动完成。程序将查找是否为字符,如果它不是一个字符则会出现一个消息,将终止该程序。如果我们有写字符,如果有大写字符将被修改为小字符,如果有小字符将是capslocks.Cant修改句号和空格。我会做一个您的示例
提供文字:
修改后的在这里写点东西。
将是:
wRITE SOMETHING HERE。
TITLE EXERC_4
CODE SEGMENT
ASSUME CS:CODE, DS:INFORMS:ss
START: MOV AX,INFORMS
MOV DS,AX
call starting
call changing
MOV SI,0
LEA DX,MESSAGE
MOV AH,9
INT 21H
MOV CX,
MOV AH,4CH
INT 21H
AGAIN:
MOV AH,1
INT 21H
CMP AL,13 ;i use ASCII for ENTER
JE CHECK
CMP AL,32; ;' ' for SPACE
JE SAVE
CMP AL,'.' ; 46 control for full stop
JE SAVE
CMP AL,'A'
JB AGAIN
CMP AL,'Z'
JBE SAVE
CMP AL,'a'
JB AGAIN
CMP AL,'z'
JA AGAIN
SAVE:
MOV BUFFER[SI],AL
INC SI
CMP SI,40
JB AGAIN
CHECK:
MOV CX,SI
JCXZ EXIT
MOV SI,0
LEA DX OUTPUT
MOV AH,9
INT 21H
START_LOOP:
MOV DL,BUFFER[SI]
CMP DL,32
JE NEXT
CMP DL,'.'
JE NEXT
CMP DL,'a'
JB CAPSLOCKS
SUB DL,32
JMP NEXT
CAPSLOCKS:
ADD DL,32
NEXT:
MOV AH,2
INT 21H
INC SI
LOOP START_LOOP
JMP END
EXIT:
LEA DX,MES_END
MOV AH,9
INT 21H
END:
MOV AH4CH
INT 21H
CODE ENDS
INFORMS SEGMENT
BUFFER 40DB dub(0)
MESSAGE DB "GIVE ONE MESSAGE :"
INFORM ENDS
END START
答案 0 :(得分:0)
1)呼叫开始。这是什么以及何时停止?与改变
相同
它将在堆栈上推送以下指令的地址(call changing
),并将ip
的值更改为标签starting
的地址。这意味着,CPU将从那里执行下一条指令,因为x86 CPU中的ip
是"指令指针"。
当它停止时 - 技术上永远不会。有指令ret
从堆栈中弹出值并将ip
设置为它,可以看作"从呼叫返回"通过人工,但从CPU的角度来看,它只是改变ip
的另一种时髦方式(所以jmp
指令的另一种变体,只是更复杂的一种,从堆栈中获取目标地址并最终当使用ret #imm16
变体时,更多地调整堆栈指针。
如果"在通话中"你更改了sp
,或者损坏了堆栈中的返回地址,ret
将无法按预期工作,因为CPU不知道是"内部有一个呼叫",它&#39 ;只需执行cs:ip
的指令 - 无论你指向哪里。
所以"当它停止" - >你掌握在"开始:"代码,你必须希望它以最终正确返回到call starting
之后的下一条指令的方式编写,你在堆栈顶部给它那个地址,但既然你有不再受控制,starting:
的代码是。
sp
寄存器指向的普通内存,它不是什么神奇的东西,所以如果你把太多的东西放进去,你就可以很容易地用完这个空间,或者你可以去如果您未正确配对sp
说明,则与push/pop
值不同步。或者你可以通过普通的方式覆盖堆栈内存,如果你以某种方式错误地计算你的修改地址,你甚至会意外地改变任何其他内存。
2)MOV AH,4CH。为什么它只有4?为什么CH背后呢?
在评论中回答。了解什么是十六进制数,以及如何将它们转换为十进制数。
您可能也想知道为什么汇编程序员经常使用十六进制格式。主要原因是,每个十六进制数字恰好由4位组成。因此,当您使用位掩码时,我可以立即从字节值37h
告知设置了5位(以及哪些是:0011 0111
)。如果您将小数格式的值显示为55
,我将需要计算相当长的一段时间,然后才能在我的头脑中看到这个二进制形式。
另外,你可以用源文本大小固定的方式编写十六进制数字,即。 16b值为4位数:01234h
(带前导0
,因此对0BEEFh
值也会保持固定大小... BEEFh
将与汇编程序的标签混淆。那就是为什么我喜欢C / C ++ 0x
前缀更多)
最后为什么4C
是"终止" - >因为DOS供应商这么说。有关它的服务说明,请参阅int 21h
文档。
3)JBE SAVE。我想保存它。
JBE
代表"在低于或等于"时跳跃。查看任何docs。
4)MOV BUFFER [SI],AL。不知道这个
5)JCXZ退出。从什么退出?
6)LOOP START_LOOP。这是什么循环?for,do,do-while?
好吧,我要在这里描述每条指令吗?我真的不想。
BUFFER[SI]
是内存引用,因此AL
中的值存储在地址(BUFFER
+ SI
)的内存中。这与C数组语法array_var[index]
类似,但您还必须记住CPU不知道您的数组元素大小,因此对于索引word
(2个字节长)数组,您必须执行{{ 1}}或将索引值改为+ -2(因此它已经预先乘以)。
如果您阅读说明参考指南,并了解CPU的工作原理(基础知识),其他的应该是显而易见的。
7)MOV AH4CH。我的错误还是它?
它缺失","在" AH"之后。 [BUFFER + si*2]
必须有两个参数分为",",然后" AH"看起来像寄存器名称,最后是" 4CH"是"终止" MOV
的常量,紧跟在下一行,所以这是一个明显的拼写错误。