"LES"8086指令未按预期工作

My *_*ug. 6 assembly dos x86-16

我是8086大会的初学者.我正在学习我在旧货店里发现的一本90年代早期的旧书.我认为像1992年那样编程可能会很有趣.

无论如何,我已经完成了这本书,现在我已经在我的旧Win95笔记本电脑上的命令提示符下编写了一些程序.

切换到使用'les'指令后,我遇到了这个问题没有按预期工作的问题.但是,当我手动设置适当地址的ES和DI寄存器时,它确实有效.

;************************************
;   STACK SEGMENT
;************************************

TheStack SEGMENT STACK      ;STACK specifies the stack segment

    db 64 dup (THESTACK)    ;reserves 512 bytes for the stack

TheStack ENDS

;************************************
;   END STACK SEGMENT
;************************************

;************************************
;   DATA SEGMENT
;************************************

Data SEGMENT

BufAddr DD 0b8000000h

Data ENDS

;************************************
;   END DATA SEGMENT
;************************************

;************************************
;   CODE SEGMENT
;************************************

Code SEGMENT

assume CS:Code,DS:Data

MAIN PROC

Start: ;execution begins

    ;setup input for stosw
    les di, DWORD PTR BufAddr
    mov cx,0f4fh  ;cx contains the number of times stosw will loop
    cld

    ;draw smileys
    mov ax,0f01h ;0f is the text attribute for white on black, 01 is the hex code for a smiley
    rep stosw ;write it all to the buffer

   ;EXIT
    mov AH,4CH ;Setup the terminate dos process service 
    mov AL,0 ;ERRORLEVEL takes 0
    int 21H  ;return to dos

MAIN ENDP 

Code ENDS 

;************************************
;   END CODE SEGMENT
;************************************

END Start ;Start is the Main procedure
Run Code Online (Sandbox Code Playgroud)

好的,所以这个程序应该在命令提示符窗口中绘制一堆笑脸ascii字符,但它不起作用.

当我用以下代码行替换'LES'行时,它确实有效.

mov bx,0b800h
mov es,bx
xor di,di
Run Code Online (Sandbox Code Playgroud)

与BufAddr变量一起使用时,'LES'指令是否与前三行代码完全相同?

当我调试编译的exe(我使用MASM 6.11作为编译器)时,我注意到ES和DI寄存器没有加载正确的值.

fuz*_*fuz 7

在加载段和从RAM偏移之前,需要将DS寄存器设置为实际指向数据段.默认情况下,DS指向您的PSP,而PSP不是您希望它指向的位置.

  • 当EXE开始运行时(在DOS EXE加载程序完成之后),_DS_是一个确定值.它恰好不是一个不会指向正确位置的值.正如罗斯指出,DOS EXE加载器存储到_DS_中的值是程序段前缀. (2认同)