DOSBox 中的问题:[ MOV SI, (160 * height)]?
Trouble in DOSBox: [ MOV SI, (160 * height)]?
在下面的代码中,我用星号注释了我遇到问题的行。如您所见,SI 包含 (160 * 8)。这是正确的值,但是,我需要更改它,而不是 (160 * 8),它应该是 (160 * height)。高度在数据段中声明为 DB。我知道我不能说 (160 * height) 但有人可以帮我解决这个问题吗?我只需要在 SI 中存储正确的值。谢谢
MyData SEGMENT
singleLine DB 0DAh, 0CFh, 0C0h, 0D9h, 0C4h, 0B3h
doubleLine DB 0CAh, 0BBh, 0C8h, 0BCh, 0CDh, 0BAh
ulCorner EQU 0
urCorner EQU 1
blCorner EQU 2
brCorner EQU 3
horLine EQU 4
verLine EQU 5
singleOrDouble DB 1
foreground DB 0001
background DB 0011
height DB 8
startCorner DW 1512
MyData ENDS
;------------------------------------------------------------------------ CODE SEGMENT
MyCode SEGMENT
ASSUME CS:MyCode, DS:MyData
MainProg PROC
MOV AX, MyData
MOV DS, AX
MOV AX, 0B800h
MOV ES, AX
CALL drawBox
MOV AH, 4Ch
INT 21h
MainProg ENDP
drawBox PROC
MOV AH, foreground
MOV AL, singleLine + ulCorner
MOV BX, startCorner
MOV ES:[BX], AX
MOV AL, singleLine + blCorner
MOV SI, 160 * 8 ;*****************height = 8********************
MOV ES:[BX + SI], AX
RET
drawBox ENDP
MyCode ENDS
您可以使用 mov
将内存中的值加载到寄存器中,例如 ax
,并且可以将寄存器与常量值相乘 mul
或 imul
.
您也可以使用 mov
在寄存器之间传输,或者,如果在两个特定寄存器之间不可用,例如 push ax; pop si
.
所以,虽然我已经很多年没做过 x86 汇编程序了,但我会从这里开始:
push ax ; Save registers we're using.
push bx
xor ax, ax ; Get height value.
mov al, [height]
mov bx, 160 ; Multiply by 160.
mul bx
push ax ; Copy to SI.
pop si
pop bx ; Restore registers.
pop ax
您可以将类似的东西注入 nasm
,但乘以 3 而不是 160(因为退出代码是有限的):
section .text
global _start
_start:
push ax ; Save registers.
push bx
xor ax, ax ; Get height value (8).
mov al, [height]
mov bx, 3 ; Triple.
mul bx
push ax ; Move to SI.
pop si
pop bx ; Restore registers.
pop ax
xor ebx, ebx ; Return result as exit code
push si
pop bx
mov eax, 1
int 0x80
section .data
height db 8
汇编、链接和 运行 该代码,然后检查退出值会给您正确的结果,8 * 3 = 24
:
pax$ nasm -f elf demo.asm
pax$ ld -m elf_i386 -s -o demo demo.o
pax$ ./demo ; echo $?
24
在下面的代码中,我用星号注释了我遇到问题的行。如您所见,SI 包含 (160 * 8)。这是正确的值,但是,我需要更改它,而不是 (160 * 8),它应该是 (160 * height)。高度在数据段中声明为 DB。我知道我不能说 (160 * height) 但有人可以帮我解决这个问题吗?我只需要在 SI 中存储正确的值。谢谢
MyData SEGMENT
singleLine DB 0DAh, 0CFh, 0C0h, 0D9h, 0C4h, 0B3h
doubleLine DB 0CAh, 0BBh, 0C8h, 0BCh, 0CDh, 0BAh
ulCorner EQU 0
urCorner EQU 1
blCorner EQU 2
brCorner EQU 3
horLine EQU 4
verLine EQU 5
singleOrDouble DB 1
foreground DB 0001
background DB 0011
height DB 8
startCorner DW 1512
MyData ENDS
;------------------------------------------------------------------------ CODE SEGMENT
MyCode SEGMENT
ASSUME CS:MyCode, DS:MyData
MainProg PROC
MOV AX, MyData
MOV DS, AX
MOV AX, 0B800h
MOV ES, AX
CALL drawBox
MOV AH, 4Ch
INT 21h
MainProg ENDP
drawBox PROC
MOV AH, foreground
MOV AL, singleLine + ulCorner
MOV BX, startCorner
MOV ES:[BX], AX
MOV AL, singleLine + blCorner
MOV SI, 160 * 8 ;*****************height = 8********************
MOV ES:[BX + SI], AX
RET
drawBox ENDP
MyCode ENDS
您可以使用 mov
将内存中的值加载到寄存器中,例如 ax
,并且可以将寄存器与常量值相乘 mul
或 imul
.
您也可以使用 mov
在寄存器之间传输,或者,如果在两个特定寄存器之间不可用,例如 push ax; pop si
.
所以,虽然我已经很多年没做过 x86 汇编程序了,但我会从这里开始:
push ax ; Save registers we're using.
push bx
xor ax, ax ; Get height value.
mov al, [height]
mov bx, 160 ; Multiply by 160.
mul bx
push ax ; Copy to SI.
pop si
pop bx ; Restore registers.
pop ax
您可以将类似的东西注入 nasm
,但乘以 3 而不是 160(因为退出代码是有限的):
section .text
global _start
_start:
push ax ; Save registers.
push bx
xor ax, ax ; Get height value (8).
mov al, [height]
mov bx, 3 ; Triple.
mul bx
push ax ; Move to SI.
pop si
pop bx ; Restore registers.
pop ax
xor ebx, ebx ; Return result as exit code
push si
pop bx
mov eax, 1
int 0x80
section .data
height db 8
汇编、链接和 运行 该代码,然后检查退出值会给您正确的结果,8 * 3 = 24
:
pax$ nasm -f elf demo.asm
pax$ ld -m elf_i386 -s -o demo demo.o
pax$ ./demo ; echo $?
24