您好我正在尝试从用户逐个字符获取字符串,然后将该字符串的反向存储在未初始化的变量中。在我想要显示未初始化的变量之后。我知道还有其他方法可以使用但我希望使用字符串操作我认为std指令可以用来以相反的顺序遍历字符串。我知道cld用于从左到右设置顺序。我还检查了教科书,并在使用后使用std和popf之前说了pushf。如果是这种情况,则应该放置推送和弹出的位置。
INCLUDE PCMAC.INC
.MODEL SMALL
.386
.STACK 128
;================================================
.DATA
prompt1 DB 13, 10,'Enter a character(Press ENTER to end Expression): $'
prompt2 DB 'Are you done ?: $'
prompt3 DB 13, 10,'Not valid choice try again', 13, 10,'$'
userExp DB 50 DUP (?)
bwUserExp DB 50 DUP (?)
validity DB 'Invalid$','Valid$'
;================================================
.CODE
EXTRN PutStr : NEAR, GetCh : NEAR, PutCh : NEAR
Main PROC NEAR
mov ax, @DATA
mov ds, ax
mov es, ax
xor bx, bx ;Clears bx register
xor cx, cx ;Clears cx register
DispPrompt: _PutStr prompt1 ;Displays prompt1 to screen
GetEXP: _GetCh al ;Gets character from user
cmp al, 13 ;Compares character
;to Carriage return
je LoadUserExp ;If equal to the carriage
;return user jumps to
;LoadUserExp
cmp al, 97 ;Compares character to a
jge AddtoExp ;If equal or greater than
;a user jumps to AddtoExp
cmp al, 122 ;Compares character to z
jle AddtoExp ;If equal or greater than
;a user jumps to AddtoExp
jmp GetEXP ;Jumps to GetEXP if character
;is not any of the matching
;characters
AddtoExp: mov userExp + bx, al ;Adds character from
;al to userExp array
inc bx ;increments bx to
;increment the position
;in the array
jmp GetEXP ;Jumps to GetEXP
LoadUserExp:
mov si, OFFSET userExp ;Loads userExp into si
mov di, OFFSET bwUserExp ;Loads bwUserExp into di
std ;Tells the program to
;go from Right to the Left
mov cx, bx ;Moves bx (the size of the array) into cx
rep movsb ;Moves the contents of si into di
DispLoop:
mov cx, bx ;Moves bx (the size of the array) into cx
xor bx, bx ;Clears the bx register
DisplayExp: mov al, bwUserExp + bx ;Moves the character
;in position bx into al
_PutCh al ;Displays the value of
;al to the screen
inc bx ;increments bx to increment
;the position in the array
dec cx ;Decrements cx
jcxz done ;Jumps to done if
;cx is zero
jmp DisplayExp ;Jumps to DisplayExp
; if cx is not zero
done: mov ax, 4c00h
int 21h
Main ENDP
;================================================
END Main
答案 0 :(得分:1)
您的代码显示了几个问题,但让我们关注“字符串” 指令。
cld
会将FLAGS
寄存器中的DF设置为零。 std
会将DF设置为1。
pushf
建议的目的是保留原始的DF
值,即pushf + popf
封闭对应该围绕整个操作,在那里修改DF,以保留原始值,如果您的代码是唯一运行的代码,而不是从外部函数调用,则可以决定不关心原始DF。
在x86调用约定中,通常决定DF预期为零,然后您不需要保留原始值,只需要在代码的每个部分之后清除DF,这需要DF = 1,在调用其他子程序之前。这种约定通常很有效,因为在极少数情况下你需要DF = 1.
movs
反向字符串 movs[b/w/d]
将从[ds:si]
加载值并将其存储到[es:di]
,然后通过添加(si
和di
来调整++si
和--di
当DF = 0)元素大小或减去(DF = 1)元素大小时。
所以你无法做movsb
和di
,这需要在指令中间翻转DF。 movsb
因此不适合您的需求。
除此之外,您正在使用缓冲区开头的地址加载userExp
,因此即使bwUserExp
可以执行您想要的操作,也会覆盖 mov si, OFFSET userExp ; source buffer
lea di, [bx + bwUserExp - 1] ; end(!) of destination buffer
mov cx, bx ; cx = size of user input
reverse_loop:
cld ; DF=0
lodsb ; al = one character, ++si
std ; DF=1
stosb ; store character, --di
dec cx
jnz reverse_loop
cld ; DF=0 for future use
缓冲区而不是写入结果进入 mov si, OFFSET userExp ; source buffer
lea di, [bx + bwUserExp] ; beyond end of destination buffer
mov cx, bx ; cx = size of user input
reverse_loop:
mov al,[si]
dec di
inc si
mov [di],al
dec cx
jnz reverse_loop
; di points at bwUserExp here
缓冲区。
您可以像这样使用字符串指令:
...
cmp al, 97 ;Compares character to a
jge AddtoExp ;If equal or greater than
;a user jumps to AddtoExp
cmp al, 122 ;Compares character to z
jle AddtoExp ;If equal or greater than
;a user jumps to AddtoExp
jmp GetEXP ;Jumps to GetEXP if character
;is not any of the matching
;characters
正如你所看到的,它不是最漂亮的代码片段,并且看起来不合理,字符串指令不适合你的任务,你应该在没有它们的情况下完成任务,如下所示:
~
...
cmp al, 'a'
jb GetEXP ; ignore characters below 'a'
cmp al, 'z'
ja GetEXP ; ignore characters above 'z'
AddtoExp:
... valid 'a'..'z' input, add to buffer ...
这允许用户输入例如 dec cx ;Decrements cx
jcxz done ;Jumps to done if
;cx is zero
jmp DisplayExp ;Jumps to DisplayExp
(126)作为有效字符,因为126> = 97.此外,我总是对与ASCII字符一起使用的signed-math分支不满意,因为我认为ASCII字符为无符号,但在技术上不会改变你的情况,因为你只对97..122范围感兴趣,所以输入一些代码大于128的DOS字符(不是常规的ASCII)被视为负值对你好。
您可以修复+简化逻辑:
dec cx ;Decrements cx
jnz DisplayExp ;Jumps to DisplayExp until cx is zero
和
m014.text = [NSString stringWithFormat:@"<html><head><style type='text/css'>body {background-color: transparent;border: 0px;margin: 0px;padding: 0px;font-family: '%@'; font-size: %fpx;;ccolor:;}</style></head><body dir='%@'>%@<style type='text/css'> iframe { width: 100%% !important; } img {width: 100%% !important; height: auto;} table {width: 100%%;}</style></body></html>", localize(@"myFontName"), @16, localize(@"myDir"), m014.text];
m014.attributedText = [[NSAttributedString alloc] initWithData: [m014.text dataUsingEncoding:NSUTF32StringEncoding] options: @{ NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType } documentAttributes: nil error: nil];
......虽然这有效,但你可以做得更简单,更高效:
[m014.text dataUsingEncoding:NSUTF32StringEncoding]