Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/assembly/5.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_X86 16 - Fatal编程技术网

Assembly 如何使语句完美地工作?

Assembly 如何使语句完美地工作?,assembly,x86-16,Assembly,X86 16,我可以用变量值初始化Cx寄存器吗? 如下图所示 MOV Cx, varaible 如果没有,那么如何使用用户输入值动态初始化Cx?请帮忙 这不是关于名字,而是关于精神形象。程序集中没有变量 对于机器来说,只有寄存器、内存、地址和使用指令访问内存。变量是程序员的逻辑结构,程序员决定以这样的方式编写代码,即使用内存作为“变量”。但是如果他决定不这样做,或者犯了一个错误,那么它将不会表现为变量,机器不会在意 例如,在您的代码中,您为.data部分中的“variable”分配内存: .Data var

我可以用变量值初始化Cx寄存器吗? 如下图所示

MOV Cx, varaible

如果没有,那么如何使用用户输入值动态初始化Cx?请帮忙

这不是关于名字,而是关于精神形象。程序集中没有变量

对于机器来说,只有寄存器、内存、地址和使用指令访问内存。变量是程序员的逻辑结构,程序员决定以这样的方式编写代码,即使用内存作为“变量”。但是如果他决定不这样做,或者犯了一个错误,那么它将不会表现为变量,机器不会在意

例如,在您的代码中,您为
.data
部分中的“variable”分配内存:

.Data
var DB ?
这将转换为符号
var
,它实际上是内存中的地址。它还将在
.data
部分中保留单个字节,因此接下来定义到该部分的任何内容都将在此之后分配。如果在下一行添加
var2 DB 13
,则
var2
地址将等于
var+1
。您还可以使用相同的地址创建多个符号,如下所示:

.Data
var:
var2:
    DB ?
根据这种定义,
var
var2
符号都指向相同的内存地址

看起来你的“变量”心理图像仍然与此兼容,所以我将演示“记忆”和“变量”之间的另一个区别:

这会将
AL
中的8位值写入地址
var
处的内存中。到现在为止,一直都还不错。现在你问:

MOV CX, [var]
这将编译并执行,但不会按预期工作。因为您只在内存中写入了8位,并且只为
var
保留了1个字节。但是
CX
是16位寄存器(由
CH
高8位和
CL
低8位组成),因此此指令将从地址
var
的内存中读取两个字节。x86是小端字节,所以当CPU使用16位值时,它将低8位映射为第一个字节(偏移量+0),高8位映射为第二个字节(偏移量+1)。因此,这将使用从
AL
存储的值加载
CL
,并使用某个值加载
CH
,该值恰好位于
var
之后的内存中。如果在
var
之后添加
var2 DB 13
,则
CH
将等于值
13
,因此总
CX
值将为
13*256+
。如果存储的
AL
为7,则
CX=3335
(或采用十六进制格式
0D07h
,这很好地显示了两个字节的值,
D
=13,
7
=7)

因此,如果要将存储的8位值正确读入
CX
,必须将其从8位扩展到16位。如果使用80386+指令集,则有专门的指令:

MOVZX cx,BYTE PTR [var]    ; zero-extend value ("unsigned" arithmetic)
MOVSX cx,BYTE PTR [var]    ; sign-extend value ("signed" arithmetic)
对于80386之前的CPU,必须计算该值,一种可能的方法是:

XOR cx, cx     ; clear all 16bits of CX to zero
MOV cl, [var]  ; fetch only low 8 bits from memory
; CX is now zero-extended 16 bit value of [var] (like MOVZX)

MOV ch, [var]  ; fetch 8 bit value into upper 8 bits of CX
SAR cx, 8      ; use right shift by 8 bits to sign-extend the value
; CX is now sign-extended 16 bit value of [var] (like MOVSX)
; this code is not optimal on 586+ CPUs, but then use MOVSX

这就是“仅内存”和“变量”之间的主要区别,程序集不会保护您,它会让您读取/写入变量之外的内存,您的任务是编写正确的代码,考虑数据大小,并分配/保留足够的内存。另外,手动执行所有指针数学运算,即如果要创建字数组(16位值),则必须按*2缩放索引以计算正确的字节地址(而C/C++将对您隐藏指针数学运算,因此只需执行[i],而*2由编译器在内部完成)。

“一个变量值”显示“变量”的定义。“用户输入值”如何输入此变量?您是在说汇编语言还是内联汇编语言?先生,我有以下代码。数据变量DB?在主程序MOV ah内,01 INT 21H;然后我将值从Al寄存器移动到变量var MOV var,Al;然后我初始化cx如下MOV cx,varI我说的是汇编语言,但你说的是变量。汇编语言中的变量?内联确保有变量,因为这是C或其他,但汇编语言中有标签(地址)(或直接)。我喜欢像编译器那样将变量视为不绑定到特定位置的逻辑实体。因此,变量可以在函数的某些部分的寄存器中,也可以在其他部分的内存中。我真的不喜欢通用的asm术语,即只使用“变量”来描述带有标签的静态存储。所以+1表示反对,尽管你们并没有提到在寄存器中保存变量。
XOR cx, cx     ; clear all 16bits of CX to zero
MOV cl, [var]  ; fetch only low 8 bits from memory
; CX is now zero-extended 16 bit value of [var] (like MOVZX)

MOV ch, [var]  ; fetch 8 bit value into upper 8 bits of CX
SAR cx, 8      ; use right shift by 8 bits to sign-extend the value
; CX is now sign-extended 16 bit value of [var] (like MOVSX)
; this code is not optimal on 586+ CPUs, but then use MOVSX