Function as8088中的变量初始化

Function as8088中的变量初始化,function,assembly,x86,as88,x86-16,Function,Assembly,X86,As88,X86 16,我目前正在编写一个函数,它基本上应该只将字符串中的字符写入变量 当执行测试打印时,我的变量看起来很好。但是,当我尝试在函数外部打印分配的第一个变量(inchar)时,它返回一个空字符串,但第二个变量(outchar)似乎返回良好。我是否以某种方式覆盖了第一个变量 这是我的代码: _EXIT = 1 _READ = 3 _WRITE = 4 _STDOUT = 1 _STDIN = 1 _GETCHAR = 117 MAXBUFF = 100 .SECT .TEXT start: 0:

我目前正在编写一个函数,它基本上应该只将字符串中的字符写入变量

当执行测试打印时,我的变量看起来很好。但是,当我尝试在函数外部打印分配的第一个变量(inchar)时,它返回一个空字符串,但第二个变量(outchar)似乎返回良好。我是否以某种方式覆盖了第一个变量

这是我的代码:

_EXIT   = 1
_READ   = 3
_WRITE  = 4
_STDOUT = 1
_STDIN = 1
_GETCHAR = 117
MAXBUFF = 100

.SECT .TEXT
start:
0:  PUSH    endpro2-prompt2
    PUSH    prompt2
    PUSH    _STDOUT
    PUSH    _WRITE
    SYS
    ADD SP,8
    PUSH    4
    PUSH    buff
    CALL    getline
    ADD SP,4
    !!!!!!!!!
    PUSH    buff
    CALL    gettrans
    ADD SP,4
    ADD AX,1 !gives AX an intial value to start loop
1:  CMP AX,0
    JE  2f
    PUSH    endpro-prompt1
    PUSH    prompt1
    PUSH    _STDOUT
    PUSH    _WRITE
    SYS
    ADD SP,8
    PUSH    MAXBUFF
    PUSH    buff
    CALL    getline
    ADD SP,2
    !PUSH   buff
    !CALL   translate
    !ADD    SP,4
    JMP 1b
2:  PUSH    0               ! exit with normal exit status
    PUSH    _EXIT           
    SYS

getline:
    PUSH    BX
    PUSH    CX
    PUSH    BP
    MOV BP,SP
    MOV BX,8(BP)
    MOV CX,8(BP)
    ADD CX,10(BP)
    SUB CX,1

1:  CMP CX,BX
    JE  2f
    PUSH    _GETCHAR
    SYS

    ADD SP,2
    CMPB    AL,-1
    JE  2f
    MOVB    (BX),AL
    INC BX
    CMPB    AL,'\n'
    JNE 1b

2:  MOVB    (BX),0
    MOV AX, BX
    SUB AX,8(BP)
    POP BP
    POP CX
    POP BX
    RET
gettrans:
    PUSH    BX
    PUSH    BP
    MOV BP,SP
    MOV BX,6(BP) !Store argument in BX
    MOVB    (inchar),BL ! move first char to inchar


1:  INC BX
    CMPB    (BX),' '
    JE  1b
    MOVB    (outchar),BL !Move char seperated by Space to outchar

    MOV AX,1    !On success
    POP BP
    POP BX
    RET

.SECT .BSS
buff:
    .SPACE  MAXBUFF

.SECT .DATA
prompt1:
    .ASCII  "Enter a line of text: "
endpro:

prompt2:
    .ASCII  "Enter 2 characters for translation: "
endpro2:    

outchar:
    .BYTE   0
inchar:
.BYTE   0
charct:
    .BYTE   0
wordct:
    .BYTE   0
linect:
    .BYTE   0
inword:
    .BYTE   0
这是用于测试打印的代码

PUSH    1       ! print that byte
PUSH    inchar
PUSH    _STDOUT
PUSH    _WRITE
SYS
ADD SP,8
CALL    printnl !function that prints new line

PUSH    1       ! print that byte
PUSH    outchar
PUSH    _STDOUT
PUSH    _WRITE
SYS
CALL printnl
ADD SP,8
指令
MOV(inchar),BX
将寄存器
BX
存储到标有
inchar
的内存位置

但是,
inchar
被定义为
.BYTE
,但是
BX
是一个16位寄存器(2字节),因此您不仅要写入
inchar
,还要写入
outchar

它在一开始工作的唯一原因是8088是一种低端体系结构,因此先存储
BX
的低位字节,然后存储高位字节


因此,尝试一下
MOV(inchar),BL
似乎有许多
as88
8088模拟器环境。但我注意到,在上面提到的许多代码库中:

我建议在您的代码中,在as88环境出现类似问题时,在数据之后移动BSS部分


在原始代码中,您有如下行:

MOV (outchar),BX
[snip]
MOV (inchar),BX
PUSH    (inchar)
[snip]
PUSH    (outchar)
MOVB    CL, (BX)
MOVB    (inchar),CL ! move first char to inchar
您将outchar和inchar定义为字节。上面的两行将2个字节(16位)从BX寄存器移动到两个单字节变量。这将导致CPU将额外的字节写入内存中的下一个变量。您可能希望显式移动单个字节。像这样的事情可能更合适:

MOVB (outchar),BL
[snip]
MOVB (inchar),BL
正如您将看到的,正如我在后面的回答中提到的,这段代码仍然有一个bug。为了澄清,MOVB指令将从BL中移动一个字节,并将其放入变量中


当您对Write执行SYS调用时,需要传递要打印的缓冲区地址,而不是缓冲区中的数据。你有两行这样的话:

MOV (outchar),BX
[snip]
MOV (inchar),BX
PUSH    (inchar)
[snip]
PUSH    (outchar)
MOVB    CL, (BX)
MOVB    (inchar),CL ! move first char to inchar
括号表示获取变量中的值并将其推送到堆栈上。SYS WRITE要求显示字符的地址。推送其地址的代码应如下所示:

PUSH    inchar
[snip]
PUSH    outchar
    MOVB   (inchar),BL ! move first char to inchar

gettrans
函数在处理从一个缓冲区到另一个缓冲区的字节副本时存在严重缺陷。您有这样做的代码:

    MOV BX,6(BP) !Store argument in BX
    MOVB    (inchar),BL ! move first char to inchar

1:  INC BX
    CMPB    (BX),' '
    JE  1b
    MOVB    (outchar),BL !Move char seperated by Space to outchar
MOV BX,6(BP)
正确放置作为参数传递的缓冲区地址,并将其放入BX中。下面的行似乎有问题:

PUSH    inchar
[snip]
PUSH    outchar
    MOVB   (inchar),BL ! move first char to inchar
这并不是评论所建议的那样。上一行将BX中缓冲区地址的低位字节(BL)移动到变量inchar。您希望将字节移动到BX指向的内存位置,并将其放入inchar。不幸的是,在x86上,无法将数据从一个内存操作数直接移动到另一个内存操作数。要解决这个问题,您必须将数据从BX指向的缓冲区移动到临时寄存器(我将选择CL),然后将其移动到变量。代码可能如下所示:

MOV (outchar),BX
[snip]
MOV (inchar),BX
PUSH    (inchar)
[snip]
PUSH    (outchar)
MOVB    CL, (BX)
MOVB    (inchar),CL ! move first char to inchar
然后,您必须对outchar执行相同的操作,以便两个位置的修复看起来都类似于此:

    MOV BX,8(BP) !Store argument in BX
    MOVB    CL, (BX)
    MOVB    (inchar),CL ! move first char to inchar

1:  INC BX
    CMPB    (BX),' '
    JE  1b

    MOVB    CL, (BX)
    MOVB    (outchar),CL ! move second char to outchar

如何调用
gettrans
?进行了编辑!如果这有助于发现问题的话,我可以发布我的全部代码。-迈克尔·佩奇在做了那些建议的更改后,我的结果似乎保持不变。如果我指向地址而不是内容,我的程序会为outchar返回'r',为inchar返回'p'。我会再搞一点的。谢谢你到目前为止的帮助。你能发布你所有的代码吗?这是另一个目前没有被使用的函数,它被注释掉了。它应该对事情没有影响。我已经尝试过了,请看一下上面的编辑。它似乎没有解决这个问题,而且MOV应该是MOVB(MOV似乎没有编译)
gettrans
仍然包含
MOV(inchar),BX
。在任何情况下,在没有明确描述a)确切发生了什么,b)准确预期会发生什么的情况下对此进行故障排除都是毫无意义的。如果我指出一个错误,而你纠正了它,那么原来的问题可能已经解决了,你可能只是在代码中面临下一个问题,但这应该是一个关于stackoverflow的新问题。这个程序现在的目标是在一行中读取,该行由两个字符组成,用空格隔开。我想获取第一个字符并将其存储在变量(inchar)中我想获取第二个变量并将其存储在(outchar)中。目前,我的程序打印一条提示-->用户可以输入4个字节(一个字符、一个空格、另一个字符、一个换行符-->此数据存储在buff-->中,然后将buff作为参数推送到我的函数gettrans->gettrans MOVB第一个字符(BL)到(inchar),然后检查一个空格->如果找到一个空格,则将该字符从BL移动到(outchar),然后再从我在代码MOV(inchar)中看到的内容(inchar),BX不再在gettrans中。请参考新代码(包含所有内容),而不是顶部列出的代码。抱歉造成混淆。不确定是否应删除以前列出的代码,因为它会使其他注释无效。