汇编程序处理字符串

Assembler Work With Strings

一个任务:

制作程序,显示最后 20 个字符。 我做了但是,程序只能使用 47 长度的字符串。 如何制作适用于任意长度线路的通用程序。

MASM:

.model small
.stack 100h
.data 
Original_string db 'Assembler language is the fatster in the world.',13,10,'$'
Formed_line db 255 DUP(?)

.code
.386
main:
mov ax,@data;
mov ds,ax;
mov es,ax;

mov dx,offset Original_string
mov ah, 9
int 21h

cld
mov ecx,LENGTHOF Original_string
sub ecx, 27                     ;47-20 =17
mov esi,[OFFSET Original_string]+27
mov edi,OFFSET Formed_line
rep movsb

mov dx,offset Formed_line
mov ah,9
int 21h
mov ax,4C00h
int 21h
end main

谢谢。

"fatster" - 国际大会语言委员会不赞成这一点,正在进行的节食被认为相当成功。

为了减少代码中的值 47,20,27,请尽量减少它们在代码中的使用。


mov ecx,LENGTHOF Original_string

是输入参数,像这样的东西将永远存在,即使你从用户那里获取输入字符串(然后你必须调用某种 strlen 函数而不是 mov ecx,<number> )。 = 好


sub ecx, 27                     ;47-20 =17

27 与任务 "display last 20 chars" 无关,换个方式做吧。


mov esi,[OFFSET Original_string]+27

字符串开头的地址又是输入参数,并且必须以某种形式将其提供给任何一种编码方式,但 +27 又是一些硬编码的中间值。


基本上你应该能够用这个输入完成任务(开始序列,在屏幕上显示字符串之后):

mov   esi,OFFSET Original_string
mov   ecx,LENGTHOF Original_string

每个进一步的代码都应该只重用那些参数值,永远不要再使用 Original_string 标签,并且只使用 20 常量(因为任务是 "last 20 characters")。尝试从这 3 个基本值中计算出您需要的所有其他中间值(保留您必须多次访问的值的副本)。

实际上,使用这些输入打印原始字符串的最后 20 个字符比人们预期的要容易。由于字符串已经以 '$' 结束,您可以:

lea   edx,[esi+ecx-20]
mov   ah, 9
int   21h

完成。 esi+ecx是字符串end()的地址('$'之后的第一个字节),那么-20会将地址向后移动20个字符。

实际上你应该做-21,因为'$'不是字符串的字符,而是字符串终止符。所以 -20 只显示 19 个字符(包括 <EOL> 个字符)。

对于采用任何输入的通用算法,您应该首先测试,如果 ecx 至少为 21+,对于 shorter/empty 字符串,-21 地址将超出字符串范围。

如果您必须显示前 20 个字符,那么您需要通过使用 '$' 终止符销毁它的第 21 个字符来修改原始字符串,或者逐个字符地输出它(int 21h,ah=2 例如)并计数 20,或者将其复制到内存中 Formed_line 并添加终止符,但是 "last 20 chars" 需要其中的 none,该字符串已准备好打印内存原样,只是移动开头。