setdibits为什么在masm汇编中失败

问题描述 投票:0回答:1

我一直在向屏幕输出bitmap imagebitmap是50像素乘50像素,但是当我尝试使用DDB将位绘制到setdibits时,它失败了,然后我因为CreateCompatibleBitmap将50 x 50像素的黑色bitmap设为黑色,所以在屏幕上出现黑框。有人知道SetDIBits失败的原因或解决方法。

我的代码的主体

includelib user32.lib
include externals.asm
include wincons.asm
.data
include variables.asm
include pic.asm
.code
start proc
    mov holder, rsp
    and rsp, -16
    sub rsp, 32
    call __imp_GetDesktopWindow
    mov rcx, rax
getdcfail:
    call __imp_GetDC
    cmp rax, 0
    je getdcfail
    mov screendc, rax
    mov rcx, rax
    call __imp_CreateCompatibleDC
    mov picdc, rax
    mov rcx, rax
    mov rdx, 50
    mov r8, 50
    call __imp_CreateCompatibleBitmap
    mov rcx, picdc
    mov rdx, rax
    mov r13, rax
    mov r8, 0
    mov r9, 50
    lea r12, [pic1colorbytes]
    push r12
    lea r12, [bitmapinfo]
    push r12
    push DIB_RGB_COLORS
    call __imp_SetDIBits
    add rsp, 24
    mov rcx, picdc
    mov rdx, r13
    call __imp_SelectObject
    mov rbx, 10000000
drawscreen:
    mov rcx, screendc
    mov rdx, 0
    mov r8, 0
    mov r9, 50
    push 50
    push picdc
    push 0
    push 0
    push 0CC0020h; srccopy is hex cc0020
    call __imp_bitblt
    add rsp, 40
    dec rbx
    cmp rbx, 0
    jne drawscreen
releasedcfail:
    mov rdx, screendc
    xor rcx, rcx
    call __imp_ReleaseDC
    cmp rax, 0
    je releasedcfail
    ;mov rcx, picdc
    ;call __imp_DeleteDC
    xor rcx, rcx
    call __imp_ExitProcess
    mov rsp, holder
    ret
start endp
end

externals.asm

extern __imp_GetDC:qword
extern __imp_ReleaseDC:qword
extern __imp_GetDesktopWindow:qword
extern __imp_ExitProcess:QWORD
extern __imp_SetDIBits:qword
extern __imp_BitBlt:qword
extern __imp_CreateDIBitmap:qword
extern __imp_DeleteObject:qword
extern __imp_DeleteDC:qword
extern __imp_CreateCompatibleBitmap:qword
extern __imp_SelectObject:qword
extern __imp_CreateCompatibleDC:qword
extern __imp_GetDesktopWindow:qword

wincons.asm

DIB_RGB_COLORS equ <0>

variables.asm

align qword
holder qword ?
screendc qword ?
picdc qword ?

pic.asm是使用photoshop创建的50 x 50 dib,然后提取所有十六进制值并将其分配为字节。这是pic.asm的开始部分,整个长度为10061行]

align dword
pic1:
byte 042H
byte 04DH
byte 048H
byte 027H
byte 000H
byte 000H
byte 000H
byte 000H
byte 000H
byte 000H
byte 036H
byte 000H
byte 000H
byte 000H
bitmapinfo:
byte 028H
byte 000H
byte 000H
byte 000H
byte 032H
byte 000H
byte 000H
byte 000H
byte 032H
byte 000H
byte 000H
byte 000H
byte 001H
byte 000H
byte 020H
byte 000H
byte 000H
byte 000H
byte 000H
byte 000H
byte 012H
byte 027H
byte 000H
byte 000H
byte 023H
byte 02EH
byte 000H
byte 000H
byte 023H
byte 02EH
byte 000H
byte 000H
byte 000H
byte 000H
byte 000H
byte 000H
byte 000H
byte 000H
byte 000H
byte 000H
pic1colorbytes:
byte 0FFH
byte 0FFH
byte 0FFH
byte 000H
byte 0FFH
byte 0FFH
byte 0FFH
byte 000H
byte 0FFH
byte 0FFH
byte 0FFH
byte 000H
byte 0FFH
byte 0FFH
byte 0FFH
byte 000H
byte 0FFH
byte 0FFH
byte 0FFH
byte 000H
byte 0FFH
byte 0FFH
byte 0FFH
byte 000H
byte 0FFH
byte 0FFH
byte 0FFH
byte 000H
byte 0FFH
byte 0FFH
byte 0FFH
byte 000H
byte 0FFH
byte 0FFH
byte 0FFH
byte 000H
byte 0FFH
byte 0FFH
byte 0FFH
byte 000H
byte 0FFH
byte 0FFH
winapi assembly x86-64 masm
1个回答
0
投票

SetDIBits之所以失败,仅仅是因为我不完全理解转换。我以为当它说“所有其他参数都传递到堆栈”时,我想到的是opcode push,但这意味着用mov设置偏移量的参数。因此,当我更改调用转换时,它会输出bitmap,但以单色显示。然后,我了解到这是因为我将picdccreateCompatibleBitmap一起使用,而我需要使用screenDC,所以当我修复它可以正确输出时。

这里是固定代码,只更改了主体,其他所有内容保持不变。

includelib user32.lib
include externals.asm
include wincons.asm
.data
include variables.asm
include pic.asm
.code
start proc
    push rbp
    sub rsp, 80
    lea rbp, [rsp + 80]
    call __imp_GetDesktopWindow
    mov rcx, rax
getdcfail:
    call __imp_GetDC
    cmp rax, 0
    je getdcfail
    mov screendc, rax
    mov rcx, rax
    call __imp_CreateCompatibleDC
    mov picdc, rax
    mov rcx, screendc
    mov rdx, 50
    mov r8, 50
    call __imp_CreateCompatibleBitmap
    mov rcx, screendc
    mov rdx, rax
    mov r13, rax
    mov r8, 0
    mov r9, 50
    lea rax, [bitmapinfo + 28h]
    mov qword ptr [rsp + 20h], rax
    lea rax, [bitmapinfo]
    mov qword ptr [rsp + 28h], rax
    mov eax, 0
    mov dword ptr [rsp + 30h], eax
    call __imp_SetDIBits
    mov rcx, picdc
    mov rdx, r13
    call __imp_SelectObject
    mov rbx, 10000000
drawscreen:
    mov rcx, screendc
    mov rdx, 0
    mov r8, 0
    mov r9, 50
    mov qword ptr [rsp + 20h], 50
    mov rax, picdc
    mov qword ptr [rsp + 28h], rax
    mov qword ptr [rsp + 30h], 0
    mov qword ptr [rsp + 38h], 0
    mov qword ptr [rsp + 40h], 0CC0020h; srccopy is hex cc0020
    call __imp_bitblt
    dec rbx
    cmp rbx, 0
    jne drawscreen
releasedcfail:
    mov rdx, screendc
    xor rcx, rcx
    call __imp_ReleaseDC
    cmp rax, 0
    je releasedcfail
    ;mov rcx, picdc
    ;call __imp_DeleteDC
    xor rcx, rcx
    call __imp_ExitProcess
    mov rsp, rbp
    pop rbp
    ret
start endp
end
© www.soinside.com 2019 - 2024. All rights reserved.