有谁知道任何好的NASM或FASM教程?我正在努力学习汇编程序,但我似乎无法找到任何有用的资源.
好的,所以我知道C++,C#,Java和其他一些语言,我决定接下来学习装配,但我觉得我从一开始就碰到了坚固的砖墙.我只需要有人指出我正确的方向.
以下是问题:
我被告知,从互联网学习装配比从书本学习更好,因为装配取决于你的硬件和书籍大多是过时的.真的吗?
我有一个64位CPU,我正在使用(或至少尝试使用)FASM.我在哪里可以找到必要的文件?
我总是感到困惑,因为我见过的大部分教程都不适合我.那是因为硬件差异吗?我如何找到正确的教程?
我可以在64位计算机上运行x86和x32程序集吗?
能不能请你这么好,给我一个简单的汇编程序(可以在我的电脑上运行),评论中有细分吗?我在我的intel核心i5 CPU上运行64位Windows 10.请.
我已经完成了ARM汇编编程,我想学习英特尔汇编程序.我一直听到所提到的所有这些不同的F/M/N/ASM-但我不确定它们与我希望实现的目标有什么关系?
有人可以帮我确定一下我需要学习如何在英特尔架构上编程低级别吗?我不太明白"不同的汇编程序"如何关联,x86,IA64,AMD64/x86-64等更是如此?
如果它有任何帮助,我最熟悉Eclipse和Visual Studio 08/10 IDE.
我将一些程序集与一些c链接起来测试函数调用的成本,使用以下程序集和c源代码(分别使用fasm和gcc)
部件:
format ELF
public no_call as "_no_call"
public normal_call as "_normal_call"
section '.text' executable
iter equ 100000000
no_call:
mov ecx, iter
@@:
push ecx
pop ecx
dec ecx
cmp ecx, 0
jne @b
ret
normal_function:
ret
normal_call:
mov ecx, iter
@@:
push ecx
call normal_function
pop ecx
dec ecx
cmp ecx, 0
jne @b
ret
Run Code Online (Sandbox Code Playgroud)
c来源:
#include <stdio.h>
#include <time.h>
extern int no_call();
extern int normal_call();
int main()
{
clock_t ct1, ct2;
ct1 = clock();
no_call();
ct2 = clock(); …Run Code Online (Sandbox Code Playgroud) 我正在使用XShm扩展来在Linux中绘制和操作图像.
为了没有屏幕闪烁,我在调用XScmPutImage之后立即传递send_event = TRUE给XShmPutImageXIfEvent然后等待事件.
这样,我正在使图像绘制阻塞,以便在窗口表面上显示之前不更改图像.
通常一切正常.但有时候,当我进行密集的图像绘制时,似乎事件永远不会出现并且绘图过程会挂起.
哪里可以看到问题?是否使用适合此任务的XIfEvent?事件如何从消息队列中消失?
是否有可能XShmPutImage不发送事件(如果send_event = TRUE)或发送不同于ShmCompletion某些情况的事件?(例如某些内部错误或其他什么?)
编辑:
经过一些研究,我发现只有当窗口管理器向窗口集中生成事件时才会发生这种挂起.例如,当我通过拖动角落调整窗口大小时.
EDIT2:
我尝试了几种方法来解决这个问题,但没有成功.最后我被迫使用一些超时并在一段时间后取消等待.但当然这是肮脏的黑客攻击,无论如何我想解决它.
那么,如果send_event = TRUE,XShmPutImage不发送事件的原因是什么,或者该事件是否可能从消息队列中消失?
EDIT3:
这是有问题的代码(FASM):
cinvoke XShmPutImage, ......, TRUE
.loop:
lea eax, [.event]
cinvoke XCheckTypedEvent, [Display], [ShmCompletionEvent], eax
test eax, eax
jz .loop ; there is no message
Run Code Online (Sandbox Code Playgroud)
注意:无论事件检查是否挂起,XShmPutImage总是返回TRUE,所以我没有在它之后进行错误检查.
EDIT4:
因为请求我发布了绘图函数的整个代码.该代码使用了FASM的一些宏库,但至少这些想法是明确的(我希望)
请注意,此代码包含限制事件仅等待20毫秒的变通代码.没有这个超时,等待循环就会永远挂起.通过XShmGetEventBase按照Xshm文档中的建议调用来获取XShm事件的编号.
; Draws the image on a OS provided window surface.
proc DrawImageRect, .where, .pImage, .xDst, .yDst, .xSrc, .ySrc, .width, .height
.event XEvent
rb 256
begin
pushad …Run Code Online (Sandbox Code Playgroud) 我对组装非常新.我昨天才拿起它,我看了很多例子,但仍然无法弄清楚如何写入控制台.当我似乎以自己的方式复制它时,我总是会遇到错误.
我正在使用 DOS 启动并启动我的应用程序test.exe。该程序以实模式启动 BSP(引导处理器)并访问 APIC 表FEE0:0000以启用偏移量处的 SVI(伪向量中断)0x0F0并INIT-SIPI-SIPI使用ICR_low(偏移量 0x300)和ICR_high(偏移量 0x310)发送序列。BSP 进入循环jmp $以停止执行并让 AP(应用处理器)在地址处执行代码0000:8000并打印一个字符。
似乎消息没有发送到 AP,因为我没有看到它们中的任何一个在显示器上打印任何内容。
我在实模式下使用 FreeDos。编译我使用FASM(平面汇编程序)
我使用了OsDev手册,其中包含我用来测试的代码(经过一些修改)尽可能简单,看看我是否可以让它工作。我还参考了英特尔程序员手册和其他规范以及 Code Project 中的教程。
我只是想唤醒 AP 并执行一些简单的代码。我发现的所有示例都进入了虚幻模式、保护模式、长模式或专注于多核处理。我写这段代码只是为了理解它是如何工作的。
我的代码是:
format MZ
USE16
start:
mov ax, cs
mov ds, ax
mov es, ax
mov ss, ax
xor sp, sp
cld
;Clear screen
mov ax, 03h
int 10h
;Move payload to the desired address
mov …Run Code Online (Sandbox Code Playgroud) 我正在学习amd64汇编程序,并尝试实现一个简单的Unix过滤器。由于未知的原因,甚至简化为最低版本(下面的代码),它也会随机崩溃。
我试图在GNU调试器(gdb)中调试该程序。在gdb的默认配置中,该程序运行良好,但是如果启用地址随机化(set disable-randomization off),该程序将开始崩溃(SIGSEGV)。清单中标记了有问题的说明:
format ELF64 executable
sys_read = 0
sys_write = 1
sys_exit = 60
entry $
foo:
label .inbuf at rbp - 65536
label .outbuf at .inbuf - 65536
label .endvars at .outbuf
mov rbp, rsp
mov rax, sys_read
mov rdi, 0
lea rsi, [.inbuf]
mov rdx, 65536
syscall
xor ebx, ebx
cmp eax, ebx
jl .read_error
jz .exit
mov r8, rax ; r8 - count of valid bytes in input buffer
xor r9, r9 ; …Run Code Online (Sandbox Code Playgroud) 我学会了使用基于DOS的简单Bootloader切换到保护模式。该加载程序加载kernel.bin到缓冲区中,并将缓冲区复制到100000h(内核为8KiB)。然后将控制权转移到内核。当我从内核返回并尝试切换到实模式时,我遇到了一个问题。
我的FASM汇编代码(类似于我先前的Stackoverflow问题)如下:
format MZ
push cs
pop ds
mov eax,cs
shl eax,4
mov [AdresSegmentuProgramu_32],eax ;Calculating real mode segment
add eax,gdt_table
mov [gdtr+2],eax
mov ax,[AdresSegmentuProgramu_32+2]
mov [code_realsegment_descriptor+3],ax
mov al,[AdresSegmentuProgramu_32+1] ;Setting 16-bit descriptors to return from protected mode
mov [code_realsegment_descriptor+2],al
mov ax,[AdresSegmentuProgramu_32+2]
mov [data_realsegment_descriptor+3],ax
mov al,[AdresSegmentuProgramu_32+1]
mov [data_realsegment_descriptor+2],al
mov ax,3d00h
mov dx,NazwaPliku
int 21h
mov bx,ax
mov ax,3f00h
mov cx,8192
mov dx,KernelGDOS32
int 21h
mov ax,3e00h
int 21h
lgdt [gdtr]
mov eax,[AdresSegmentuProgramu_32]
add eax, pmode_entry ;Far jump to …Run Code Online (Sandbox Code Playgroud) 我想创建printl允许我在寄存器中打印字符串的函数ax。我处于 16 位实模式,找不到任何打印消息的方法。我用来int 0x10打印一封信。
我尝试在寄存器中传递参数(要打印的字符串)bx,然后在循环中逐个字母地打印,然后使用popaand返回ret。我的代码并没有真正起作用——要么它创建了一个无限循环,要么打印了一个奇怪的符号。
如果您知道更有效的方法,那么这不是问题。如果您提供任何评论,我还想询问您的代码
这是我的代码
启动.asm:
start:
mov bx, welcome ;put argument to bx
call printl ;call printl function in sysf.asm
hlt ;halt cpu
welcome db 'Hello', 0
include 'sysf.asm'
times 510 - ($-$$) db 0
db 0x55
db 0xAA
Run Code Online (Sandbox Code Playgroud)
sysf.asm:
;print function
; al is one letter argument (type Java:char)
;
print:
pusha
mov ah, 0x0e
int 0x10
popa
ret ; go back
;printl function …Run Code Online (Sandbox Code Playgroud)