Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/apache-flex/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Assembly 使用汇编语言程序交换两个字符串变量的内容_Assembly - Fatal编程技术网

Assembly 使用汇编语言程序交换两个字符串变量的内容

Assembly 使用汇编语言程序交换两个字符串变量的内容,assembly,Assembly,我是个新手。我试图交换两个字符串变量的内容。我有一个代码,用来交换两个内存变量。这是代码- DATA SEGMENT NUM1 DB 9H NUM2 DB 7H ENDS CODE SEGMENT ASSUME DS:DATA CS:CODE START: MOV AX,DATA MOV DS,AX MOV AL,NUM1 MOV BL,NUM2 XCHG AL,NUM2 XCHG BL,NUM1 MOV AH,4CH INT 21H E

我是个新手。我试图交换两个字符串变量的内容。我有一个代码,用来交换两个内存变量。这是代码-

DATA SEGMENT
 NUM1 DB 9H
 NUM2 DB 7H
ENDS
CODE SEGMENT 
 ASSUME DS:DATA CS:CODE
START:
  MOV AX,DATA
  MOV DS,AX

  MOV AL,NUM1
  MOV BL,NUM2

  XCHG AL,NUM2
  XCHG BL,NUM1 

  MOV AH,4CH
  INT 21H     
ENDS
END START
请让我知道我是否可以在这里进行任何更改以获得准确的输出

    MOV    AL,NUM1
    MOV    BL,NUM2
    XCHG   AL,NUM2
    XCHG   BL,NUM1 
可缩短为(完成时:相同内存、不同寄存器):

但实际上,这个较长的版本应该性能更好(
XCHG
可能是非常昂贵的指令,因为它通常与
LOCK
前缀一起用于多处理器PC中的同步,几十年来编译器都不使用它来“交换”值,因此在现代x86 CPU中它没有针对这一点进行优化):

现在您有两个标签
NUM1
NUM2
指向同一个字节,因此您有了单个“变量”的“别名”

最后是字符串

InputString  DB "Hello$"
CPU中没有“字符串”这样的类型,因此
InputString
不能是“字符串变量”。它只是下一个定义字节的标签,机器代码中下一个定义字节的值为
'H'
,等于
72
(检查ASCII表中特定ASCII字符的值)。该行将编译为6字节的机器代码,带有(十六进制)值:

所以要“交换两个字符串的内容”,您首先需要知道,两个目标内存位置都有足够的保留字节。例如:

String1 DB "a"
String2 DB "bc"
如果您尝试交换内容,则设置为灾难,因为只有1个字节为“String1”保留,因此当您将
“bc”
写入其中时,
'c'
将实际到达地址
String2

当你知道你为两个“字符串”都保留了足够的内存时,你需要将字节内容从一个复制到另一个,反过来,你甚至可以忽略字符串的实际长度,只需逐个字节交换两个缓冲区的总内容(如
buffer1 db 100 dup(?)
buffer2 db 100 dup(?)
然后在这两个字节之间交换100个字节,而不管里面是什么)。或者,当您在较长的一个标记中达到“字符串结束”标记时,您可以通过终止条件对其进行优化

还要注意的是,程序集中并没有字符串类型,所以如何标记字符串的结尾取决于代码。由
int 21h,9
服务完成的DOS输出确实使用字符值
'$'
,但您也可以使用以值0结尾的C类字符串,甚至可以使用旧的Pascal方式,将字符串的第一个字节保留为长度值,因此
a=“Hello”以字节形式存储在内存中
0548656C6F
。如果要使用
int 21h,9
服务输出结果字符串,则必须覆盖
'$'
终止符的末尾。(还要记住,字符串的终止符实际上是它的一部分,因此100字节的保留内存足以容纳长度为99个字符的零终止字符串)

继续使用调试器观察寄存器和内存中的值,以及它们随执行的每条指令的变化情况,这将极大地加快您的学习速度,因为它非常“直观”(与阅读《英特尔指令参考指南》相比,您仍应经常阅读该指南)

NUM1:
NUM2:   DB 9
InputString  DB "Hello$"
48 65 6C 6C 6F 24
String1 DB "a"
String2 DB "bc"