我需要输入一个字符串并显示该字符串,如ASCII代码数组.我怎样才能用汇编语言实现它.
org 100h
mov ah, 9
mov dx, str1
mov byte [str1+2], [char]
int 21h
mov ah, 4Ch
int 21h
str1 db 'String$'
char db "o"
Run Code Online (Sandbox Code Playgroud)
为什么NASM会给我这个错误信息:
第5行出错:操作码和操作数的组合无效
mov byte [str1+2], [char]
Run Code Online (Sandbox Code Playgroud)
在这一行我试图将存储的字节移动*char到地址*str1+2.
我觉得好像我不理解8086汇编中断21H的功能0AH.我阅读了语法教程,例如:
"缓冲区的第一个字节指定它可以容纳的最大字符数(1到255).该值必须由用户提供.缓冲区的第二个字节由DOS设置为实际读取的字符数,不包括终止返回."
所以我尝试了一个非常基本的代码.
mov dh, 01
mov ah, 0AH
int 21H
Run Code Online (Sandbox Code Playgroud)
我运行这个程序,输入一个数值,然后按回车键.然而,Debug显示我的寄存器都没有从此操作中更改.我不知道在哪里,如果有的话,我输入的值被存储.有人可以帮我弄这个吗?
我一直在搞乱x86-16程序集并使用VirtualBox运行它.出于某种原因,当我从内存中读取并尝试将其作为角色打印时,我得到的结果与我期望的完全不同.但是,当我将字符硬编码为指令的一部分时,它工作正常.这是代码:
ORG 0
BITS 16
push word 0xB800 ; Address of text screen video memory in real mode for colored monitors
push cs
pop ds ; ds = cs
pop es ; es = 0xB800
jmp start
; input = di (position*2), ax (character and attributes)
putchar:
stosw
ret
; input = si (NUL-terminated string)
print:
cli
cld
.nextChar:
lodsb ; mov al, [ds:si] ; si += 1
test al, al
jz .finish
call putchar
jmp .nextChar
.finish:
sti
ret …Run Code Online (Sandbox Code Playgroud) 我有一个用emu8086编写的简单EXE代码,它在屏幕上移动一个字符(现在):
黄色的"*"用箭头键移动.
问题是模拟器获得16次按键.我的意思是当我如此快速地按下按键(或按住一个按键)时,它会按住按键并按下它们移动"*".例如:
在上图中,"*"根据我之前按下的键移动了14次!
我不希望它把我的按键按在堆栈中.如何根据按下的最后一个键而不是堆栈进行实时反应?
PS:这是我从用户那里按下按键的部分,在当前位置打印一个空字符并将"*"移动到新位置:
check_for_key:
; === check for player commands:
mov ah, 01h
int 16h
jz no_key
mov ah, 00h
int 16h
mov cur_dir, ah
; print ' ' at the location:
mov al, ' '
mov ah, 09h
mov bl, 0eh ; attribute.
mov cx, 1 ; single char.
int 10h
call move_star
Run Code Online (Sandbox Code Playgroud) 我编写了一个汇编程序,它在数组中找到最大值,但现在我希望它能找到数组中的第二大数字.如何修改程序来执行此操作?
这是我写的程序,它确实有效.程序打印数组中的所有值,然后查找数组的最大值.现在我希望它找到第二大值.
%include "io.mac"
.STACK 100H
.DATA
Numbers DW 3,4,5,2,6,0
msg0 db "Printing values in array",0
msg1 db "Max",0
msg2 db "Min",0
.CODE
.STARTUP
PutStr msg0
mov dx, Numbers
mov si, dx ;point to array
printValues:
cmp word [si], 0
je procedure
nwln
PutInt [si]
add si, 2
jmp printValues
procedure:
push Numbers ;push Number to stack to pass parameter by stack
call maxMeth
nwln
PutStr msg1
nwln
PutInt ax
nwln
complete:
.EXIT
maxMeth:
enter 0,0 ;save old bp and …Run Code Online (Sandbox Code Playgroud) 代码必须输出'ccb',但只输出'c',只输出LOOP一次,我已在TD中校准,但为什么LOOP只做一次?
我认为我必须减少STRING_LENGTH,所以我心烦意乱
DEC STRING_LENGTH
Run Code Online (Sandbox Code Playgroud)
但是它不起作用,所以我很喜欢这样
MOV SP,STRING_LENGTH
DEC SP
MOV STRING_LENGTH,SP
Run Code Online (Sandbox Code Playgroud)
我知道你现在正在思考什么,这是不正确的,你是对的)))
我可以使用C++,但我只想在大会上做,
DOSSEG
.MODEL SMALL
.STACK 200H
.DATA
STRING DB 'cScbd$'
STRING_LENGTH EQU $-STRING
STRING1 DB STRING_LENGTH DUP (?) , '$'
.CODE
MOV AX,@DATA
MOV DS,AX
XOR SI,SI
XOR DI,DI
MOV CX,STRING_LENGTH
S:
MOV BL,STRING[DI]
AND STRING[DI],01111100B
CMP STRING[DI],01100000B
JNE L1
MOV AL,BL
MOV STRING1[SI],AL
ADD SI,2
L1:
ADD DI,2
LOOP S
MOV DL,STRING1
MOV AH,9
INT 21H
MOV AH,4CH
INT 21H
END
Run Code Online (Sandbox Code Playgroud) 在8086中,此结构是正确的:
mov bh,[bx]
Run Code Online (Sandbox Code Playgroud)
但这是不正确的:
mov bh,[cx]
Run Code Online (Sandbox Code Playgroud)
我不知道为什么 我认为通用寄存器(AX,BX,CX,DX,SP,BP,SI和DI)是可以用于任何目的的寄存器,并且BX用于基地址或CX用于计数器的声明只是一个约定,它们完全没有区别。但是看来我错了。你能解释原因吗?这些寄存器之间的确切区别是什么?(例如,为什么不能将基址保存在cx寄存器中?)
我正在关注有关操作系统的教程,并且遇到了以下块代码,该块代码根据变量“ ImageName”检查磁盘上的文件名。
我的困惑源于push di前一行rep cmpsb。
mov cx, WORD [bpbRootEntries]
mov di, 0x0200
.LOOP:
push cx
mov cx, 0x000B
mov si, ImageName
push di
rep cmpsb
pop di
je LOAD_FAT
pop cx
add di, 0x0020
loop .LOOP
jmp FAILURE
Run Code Online (Sandbox Code Playgroud)
我找到的cmpsb状态文档“对于传统模式,将地址DS:(E)SI上的字节与地址ES:(E)DI上的字节进行比较。状态标志会相应地设置。” di在此调用之前推送不意味着我总是要与一个空值进行比较吗?该代码有效,因此我显然会误解某些东西,但是我能找到的每篇文档都暗示该代码不起作用。