Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/assembly/6.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 汇编x86-如何在变量之间移动字符串_Assembly_X86_Tasm_Dosbox - Fatal编程技术网

Assembly 汇编x86-如何在变量之间移动字符串

Assembly 汇编x86-如何在变量之间移动字符串,assembly,x86,tasm,dosbox,Assembly,X86,Tasm,Dosbox,(通过DOSBOX运行组件x86) 我正在使用过程加载图像(bmp文件),第一个过程是加载文件(打开): 我希望filename被用作文件名的全局变量—它的路径字符串,因此在运行所有进程之前,我唯一要做的就是将正确的路径移动到filename变量 filename db ? img1 db 'img1.bmp',0 img2 db 'img2.bmp',0 我认为这是某种字符串传输,我发现MOVS命令可能会有帮助,但我没有理解它的工作方式。只是一个简短的示例MOVS如何工作(其他来自“字符串”

(通过DOSBOX运行组件x86)

我正在使用过程加载图像(bmp文件),第一个过程是加载文件(打开):

我希望filename被用作文件名的全局变量—它的路径字符串,因此在运行所有进程之前,我唯一要做的就是将正确的路径移动到filename变量

filename db ?
img1 db 'img1.bmp',0
img2 db 'img2.bmp',0

我认为这是某种字符串传输,我发现MOVS命令可能会有帮助,但我没有理解它的工作方式。

只是一个简短的示例
MOVS
如何工作(其他来自“字符串”指令系列的命令也类似)

首先,您需要内存空间,因此在您的情况下,
filename
必须扩展

MAX_FILE_NAME_LENGTH    EQU  128
filename    db MAX_FILE_NAME_LENGTH dup (?)   ; reserving enough space for "string"
img1        db 'img1.bmp',0
img1length  equ $-img1
img2        db 'img2.bmp',0
img2length  equ $-img2
现在将
img2
“字符串”复制到
filename
img2
是内存中的地址,其中以下
img2length
字节由上面的
db
定义(包括零分隔符)。目标地址是
文件名
符号。
mov
将数据从
ds:si
si
作为“源”)复制到
es:di
di
作为“目标”)


另一个带有指针的变体示例:

通常的做法是将值作为参数传递给函数,在这种情况下,您可以要求调用方在调用
OpenFile
之前预先设置
ds:dx
,然后您只需在过程中省略
dx
设置代码即可,例如:

; arguments: ds:dx = pointer to ASCIIZ file name
; returns (and modifies): ax = file handle
; in case of file error "..." happens
proc OpenFile
    mov ax, 3D00h    ; ah = 3D "open file", al = 0 "read-only"
    int 21h
    jc openerror1
    ret
    openerror1:
    ... ; probably terminate app any way in case of error
然后在每次调用之前设置ds:dx,然后根据需要存储文件句柄:

    ...
    ; let's pretend the DS was already set before
    mov    dx, offset img1
    call   OpenFile
    mov    [img1FileHandle],ax
    ...
数据设置如下所示:

img1 db 'img1.bmp',0
img1FileHandle dw 2    ; DW, because handle is 16 bit "wide" (AX = 16 bits)
  ; 2 == STDERR, until the code will run OpenFile and store real handle
也可以将这些内容放入内存中的全局变量中,然后从
OpenFile
中的内存中读取它们,但如果您尝试编写这些内容,您会发现这相当麻烦,在寄存器中传递参数更简单。。。在某种程度上,直到您的代码变得足够复杂,以至于忘记了哪个过程需要哪个寄存器,然后突然变得有点混乱


从这里开始,最好遵循一些官方的调用约定,如cdecl和类似的,但16b/32b模式的大多数调用约定都使用堆栈来传递参数,这同样有点繁琐,手工编写也比通过寄存器传递值的性能差。对于小型的纯asm应用程序,可以根据需要对每个过程参数/结果进行优化,只需对每个过程进行注释,并明确说明使用了哪些寄存器。

这只是
MOV
工作原理的一个简短示例(其他“字符串”指令系列也类似)

首先,您需要内存空间,因此在您的情况下,
filename
必须扩展

MAX_FILE_NAME_LENGTH    EQU  128
filename    db MAX_FILE_NAME_LENGTH dup (?)   ; reserving enough space for "string"
img1        db 'img1.bmp',0
img1length  equ $-img1
img2        db 'img2.bmp',0
img2length  equ $-img2
现在将
img2
“字符串”复制到
filename
img2
是内存中的地址,其中以下
img2length
字节由上面的
db
定义(包括零分隔符)。目标地址是
文件名
符号。
mov
将数据从
ds:si
si
作为“源”)复制到
es:di
di
作为“目标”)


另一个带有指针的变体示例:

通常的做法是将值作为参数传递给函数,在这种情况下,您可以要求调用方在调用
OpenFile
之前预先设置
ds:dx
,然后您只需在过程中省略
dx
设置代码即可,例如:

; arguments: ds:dx = pointer to ASCIIZ file name
; returns (and modifies): ax = file handle
; in case of file error "..." happens
proc OpenFile
    mov ax, 3D00h    ; ah = 3D "open file", al = 0 "read-only"
    int 21h
    jc openerror1
    ret
    openerror1:
    ... ; probably terminate app any way in case of error
然后在每次调用之前设置ds:dx,然后根据需要存储文件句柄:

    ...
    ; let's pretend the DS was already set before
    mov    dx, offset img1
    call   OpenFile
    mov    [img1FileHandle],ax
    ...
数据设置如下所示:

img1 db 'img1.bmp',0
img1FileHandle dw 2    ; DW, because handle is 16 bit "wide" (AX = 16 bits)
  ; 2 == STDERR, until the code will run OpenFile and store real handle
也可以将这些内容放入内存中的全局变量中,然后从
OpenFile
中的内存中读取它们,但如果您尝试编写这些内容,您会发现这相当麻烦,在寄存器中传递参数更简单。。。在某种程度上,直到您的代码变得足够复杂,以至于忘记了哪个过程需要哪个寄存器,然后突然变得有点混乱


从这里开始,最好遵循一些官方的调用约定,如cdecl和类似的,但16b/32b模式的大多数调用约定都使用堆栈来传递参数,这同样有点繁琐,手工编写也比通过寄存器传递值的性能差。对于小型的纯asm应用程序,可以根据需要对每个过程参数/结果进行优化,并对每个过程进行注释,清楚说明使用了哪些寄存器。

您可以在其中存储一个指针。你知道C吗?当然,您也可以复制它,但是您需要足够的空间(顺便说一句,指针也不止一个字节)。您还可以决定
OpenFile
要求调用者预先设置
ds:dx
以指向文件名,因此它将是过程参数。然后您可以执行
mov-dx,offset-img1
调用OpenFile
。。而且,更常见的是从过程中返回
ax
中的值,所以调用方将负责将句柄存储在某个地方。这样,您就可以同时对不同的文件重用
OpenFile
。也许你可以读一些关于函数式编程的好处的书(只是不要对它过于兴奋,有些人在不了解SW有多实用的情况下就这么做了)。你可以在里面存储一个指针。你知道C吗?当然,您也可以复制它,但是您需要足够的空间(顺便说一句,指针也不止一个字节)。您还可以决定
OpenFile
要求调用者预先设置
ds:dx
以指向文件名,因此它将是过程参数。然后您可以执行
mov-dx,offset-img1
调用OpenFile
。。而且,更常见的是从过程中返回
ax
中的值,所以调用方将负责将句柄存储在某个地方。这样,您就可以同时对不同的文件重用
OpenFile