在MASM x86程序集中存储和递增整数变量
我试图理解程序集。今天的话题是:“存储和递增INT变量和印刷数字” :)在MASM x86程序集中存储和递增整数变量
因此,这里是我的代码
dane segment
count db 0
dane ends
code segment
start:
inc byte ptr ds:[count]
inc byte ptr ds:[count]
inc byte ptr ds:[count]
mov dl,ds:[count]
mov ah,2
int 21h
mov ah,4ch
int 21h
code ends
end start
当我编译和运行,我得到这个错误:
只有当count
增加一次以上时才会发生。 我在做什么错?
有人可以解释为什么我不能简单地写:
inc count
另外,为什么我必须把byte ptr
增加值的时候,但如果我把它复制到dl
注册?
编辑:更改信息,并添加文本,添加的代码(工作在MASM 6.11):
在86 assembbly你需要指定内存操作数的大小,在将有歧义,否则说明。您必须告知汇编程序的操作数大小为byte ptr
,word ptr
等。因此inc byte ptr ds:[count]
需要byte ptr
。 inc word ptr ds:[count
是不同的指令。
mov dl,ds:[count]
不需要byte ptr
,因为dl
是一个8位寄存器,因此内存操作数的大小始终相同,即一个字节(8位)。
要打印字符,首先需要将数字转换为字符串(或数字小于10的单个字符)。否则,你要打印控制字符ETX(见ASCII table)有ASCII码3.对于小于10,十进制印刷是微不足道的,只需要添加的数字“0”(30h
),像这样:
mov dl,ds:[count] add dl,'0' ; add dl,30h
在打印x86组件中的十进制是经常被问到的,例如参见Is this code correct (Number plus number, then print the result)以获得这个想法。
编辑: EXE文件还需要一个堆栈段。
DOS EXE文件需要有一个堆栈段。与MASM 6.11组装不会给出任何警告或错误,基本上与dosexe.asm
(将dosexe.asm替换为您的汇编代码文件名)。
但联用ML(ml dosexe.obj
)给出以下的警告:
LINK : warning L4021: no stack segment
所以,堆栈段需要被添加,添加下列行到源的顶部。
.model small .stack 4096
数据段定义也有问题,我也修正了。
整个固定的汇编代码可能是这样的(在MASM 6.11作品):
.model small .stack 4096 .data count db 0 .code start: mov ax,seg count mov ds,ax inc byte ptr ds:[count] inc byte ptr ds:[count] inc byte ptr ds:[count] ; this code does the printing in decimal without needing to reverse ; the string, by dividing the divisor. 100/10 = 10 mov bl,100 ; original divisor. mov al,ds:[count] print_loop: xor ah,ah ; clear top 8 bits of the dividend (in ax). div bl ; divide ax by bl. quotient in al, remainder in ah. mov dl,al ; the value to be printed with ah = 2, int 21h mov al,ah ; remainder gets divided in the next loop. test dl,dl ; check if number is zero jz not_print ; don't print leading zeros. add dl,'0' ; convert to ASCII numeric characters range. ; '0' = 0x30 = 48 push ax mov ah,2 int 21h ; print the value, according to Ralf Brown's pop ax ; interrupt list returns al. not_print: push ax mov al,bl xor ah,ah mov bl,10 ; divide the divisor by 10. div bl mov bl,al ; the new divisor. pop ax test bl,bl jnz print_loop mov ah,4ch int 21h end start
当我写“dl,ds:[计数]”,同样的东西打印所有的时间 - 无论我把什么计数:/不应该只是“mov dl,计数”?我在教程中看到了这个,但是当我这样做时,我得到了A02074错误 – msmialko 2013-03-23 10:23:48
@Moriquendi您正在使用哪种汇编语言?您需要定义数据段,但我认为其语法取决于您正在使用的汇编程序。 – nrz 2013-03-23 10:25:11
我希望我知道:P我从教授的网站上下载了MASM编译器,安装了Windows XP 32位并开始使用示例代码。我如何检查它?其他语法的外观可能如何? – msmialko 2013-03-23 10:33:02
[报价] MOV DL,DS:[计]不需要字节的PTR,因为D1是8因此内存操作数的大小总是相同的,一个字节(8位)。[/ quote]
而且此操作不需要段覆盖前缀,因为DS是默认段这个操作。 => MOV dl时,第[count]
编辑:
定义称为具有段名的程序段的属性
http://msdn.microsoft.com/de-de/library/d06y3478%28v=vs.80%29.aspx
name SEGMENT [[READONLY]] [[align]] [[combine]] [[use]] [[characteristics]] ALIAS(string) [['class']]
statements
name ENDS
实施例用于使用段名:
CODE SEGMENT use16 'CODE'
assume cs:CODE,ds:DATEN,ss:STAPEL
org 100h
START:
mov ax, DATEN
mov ds, ax
; your instructions
CODE ends
DATEN SEGMENT use32 'DATA'
org 0
VALUE DD ?
DATEN ends
STAPEL SEGMENT use16 STACK 'STACK'
DB 10h dup (0)
STAPEL ends
end
如何使用细分市场和指令:
http://cs.smith.edu/~thiebaut/ArtOfAssembly/CH08/CH08-3.html
...
对于链接使用MASM 6,我们需要的其他连接16位应用程序。
ftp://ftp.microsoft.com/softlib/mslfiles/lnk563.exe
德克
我不知道这个集会,但你肯定不会增加一个指针,而不是在寄存器中的值?这个错误信息似乎堆腐败.. – Jack 2013-03-23 17:16:30