gpt4 book ai didi

c - 组装,画图

转载 作者:行者123 更新时间:2023-11-30 18:40:39 24 4
gpt4 key购买 nike

我需要在DOS下通过Assembly(intel)+C(c99)绘制QRCode。但看来我的内存太少了。我尝试将图像存储为位数组:

image
db 11111110b,
...

但无论如何我没有结果(从 9f208c70、CS:IP 192:9f20734f 非法读取)。现在我不知道该怎么办。这是我使用的代码:

模块.asm:

[bits 16]

global setpixel
global setVM
global getch
global getPixelBlock

section .text

setVM:
push bp
mov bp, sp
mov ax, [bp+6]
mov ah, 0
int 10h
pop bp
ret

setpixel:
push bp
mov bp,sp
xor bx, bx
mov cx, [bp+6]
mov dx, [bp+10]
mov al, [bp+14]
mov ah, 0ch
int 10h
pop bp
ret

getch:
push bp
mov ah,0
int 16h
mov ah,0
pop bp
ret

getPixelBlock:
push bp
mov cx, [bp+6]
mov bx, image
add bx, cx
mov ax, [bx]
pop bp
ret

section .data
image
db 11111110b,
db 10011011b,
db 11111100b,
db 00010011b,
db 00010000b,
db 01101110b,
db 10110000b,
db 10111011b,
db 01110101b,
db 01100101b,
db 11011011b,
db 10100000b,
db 00101110b,
db 11000001b,
db 01110001b,
db 00000111b,
db 11111010b,
db 10101111b,
db 11100000b,
db 00011000b,
db 00000000b,
db 11010011b,
db 01011111b,
db 01101011b,
db 11100100b,
db 11101000b,
db 00110101b,
db 11001111b,
db 01001111b,
db 11100000b,
db 00011011b,
db 11010001b,
db 00100111b,
db 00000011b,
db 10000000b,
db 00000011b,
db 10001111b,
db 11111010b,
db 00100000b,
db 01010000b,
db 01000110b,
db 01011011b,
db 10111010b,
db 01001111b,
db 01010101b,
db 11010110b,
db 10001110b,
db 00101110b,
db 10010001b,
db 01111011b,
db 00000101b,
db 01100001b,
db 10001111b,
db 11101110b,
db 11000001b

main.c:

__asm(".code16gcc\n");

int run();
int _start()
{
return run();
} // Dirty hack to code as I used to

#include "ASM.inl"
#include "Painter.inl"

int run()
{
setVM(0x10);
_brushSize = 5;
drawLogo(30,30);
uint ret = (uint)getch();
return ret>>5;
}

ASM.inl

#ifndef __ASM_H__
#define __ASM_H__

typedef unsigned short int uint;
typedef unsigned char uchar;

void setpixel(uint x, uint y, uint color);
void setVM(uint vm);
uchar getch();
uchar getPixelBlock(uchar);

#endif /* __ASM_H__ */

画家.inl:

/**
* You can create other colors by using bitwise or
*/
enum Color {
White = 0b0111,
Black = 0b0000,
Red = 0b0100,
Green = 0b0010,
Blue = 0b0001,
Bright = 0b1000,
};

int _brushSize = 5;

void rect(uint x, uint y, uint width, uint height, uint color)
{
uint i,j;
for (i=x; i<width+x; i++) {
for (j=y; j<height+y; j++) {
setpixel(i,j,color);
}
}
}

uint getColor(uchar element, uchar offset)
{
element = element & (1 << offset) >> offset;
return element ? Black : White;
}

void drawLogo(uint x, uint y)
{
uchar current;
uchar counter = 0;
for (uint i=0; i<21; i++) {
for (uint j=0; j<21; j++) {
counter = i*21+j;
current = getPixelBlock((uchar)counter/8);
rect(x+i*_brushSize, y+j*_brushSize, _brushSize, _brushSize, getColor(current, counter%8));
}
}
}

编译脚本:

#!/bin/bash
nasm -f elf32 module.asm -o module.o
gcc -std=c99 -m32 -ffreestanding -masm=intel -c main.c -o main.o
ld -m elf_i386 -Ttext=0x100 main.o module.o -o os.com
objcopy os.com -O binary
  • GCC 版本:4.8.3(Gentoo 4.8.3 p1.1、pie-0.5.9)
  • NASM 版本:2.11.05
  • DOSBox版本:0.74

我做错了什么?也许我应该直接写入图形内存或类似的东西?或者也许我应该更改 gcc 优化?

最佳答案

汇编代码看起来总体不错。您可能希望通过在 int 10h 上设置断点并检查寄存器值来根据堆栈上的参数顺序检查中断调用序列。我已经 20 多年没有做过这些事了,我已经生疏了。

您至少有两个可能的运算符优先级问题。我不认为这些做法是正确的。

element = element & (1 << offset) >> offset;
current = getPixelBlock((uchar)counter/8);

你有一个硬编码的“神奇数字”:21。我不知道这意味着什么。

之后的问题是:它在哪里崩溃了?是时候让调试器启动并收回成本了。

<小时/>

我想问:为什么要用汇编语言写这些东西?您可以直接从 C、从 C 中的嵌入式 asm 或通过单个包装函数轻松调用 int 10h

关于c - 组装,画图,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25462807/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com