我当前正在编写一个函数,基本上应该只将字符串中的字符写入变量中。
执行测试打印时,我的变量看起来不错。但是,当我尝试在函数外部打印分配的第一个变量(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
似乎有as88
8088个模拟器环境。但是我注意到在许多代码存储库中都提到了该错误:
1. The assembler requires sections to be defined in the following order: TEXT DATA BSS After the first occurrences, remaining section directives may appear in any order.
如果您的as88环境存在类似问题,我建议您在代码中将BSS节移到DATA之后。
在原始代码中,您有如下代码:
MOV (outchar),BX
[snip]
MOV (inchar),BX
您将outchar和inchar定义为字节。上面的2行将BX寄存器中的2个字节(16位)移到两个1字节变量中。这将导致CPU将多余的字节写入内存中的下一个变量。您需要显式移动单个字节。像这样的事情可能更合适:
MOVB (outchar),BL
[snip]
MOVB (inchar),BL
正如您将看到的那样,此代码仍然有一个错误,如我稍后在此答案中提到的。为了澄清-MOVB指令将从BL中移出一个字节并将其放入变量中。
在对Write进行SYS调用时,您需要传递要打印的缓冲区地址,而不是缓冲区中的数据。您有2行是这样的:
PUSH (inchar)
[snip]
PUSH (outchar)
括号中的值表示将变量中的值放入堆栈中。SYS WRITE要求显示字符的地址。推送地址的代码应如下所示:
PUSH inchar
[snip]
PUSH outchar
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中。看起来像这样的行有问题:
MOVB (inchar),BL ! move first char to inchar
这没有按照评论的建议进行。上面的行将BX中缓冲区地址的低字节(BL)移动到变量inchar。您想将字节移动到BX指向的内存位置,并将其放入inchar中。不幸的是,在x86上,您不能将数据直接从一个内存操作数移动到另一个内存操作数。为了解决这个问题,您必须将数据从BX指向的缓冲区移动到临时寄存器中(我将选择CL),然后将其移动到变量中。代码看起来像这样:
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
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句