在运行我用汇编编写的程序时,我收到Illegal instruction错误.有没有办法知道哪个指令导致错误,没有调试,因为我正在运行的机器没有调试器或任何开发系统.换句话说,我在一台机器上编译并在另一台机器上运行.我无法在我正在编译的机器上测试我的程序,因为它们不支持SSE4.2.我正在运行程序的机器确实支持SSE4.2指令.
我想这可能是因为我需要告诉汇编程序(YASM)识别SSE4.2指令,就像我们通过传递-msse4.2标志一样使用gcc .或者你认为这不是原因吗?知道如何告诉YASM识别SSE4.2指令吗?
也许我应该捕获SIGILL信号然后解码SA_SIGINFO以查看程序执行什么样的非法操作.
假设我声明了以下内容:
section .bss
buffer resb 1
Run Code Online (Sandbox Code Playgroud)
这些说明如下:
mov al, 5 ; mov-immediate
mov [buffer], al ; store
mov bl, [buffer] ; load
mov cl, buffer ; mov-immediate?
Run Code Online (Sandbox Code Playgroud)
我是否理解bl将包含值5,并且cl将包含变量的内存地址section .text?
我对两者之间的差异感到困惑
buffervsmov cl, buffer 更新:阅读回复后,我认为以下摘要是准确的:
假设声明mov cl, [buffer]存在于mov edi, array.我的理解是:
edi将第0个数组索引的内存地址放入mov byte [edi], 3.add edi, 3 将VALUE 3放入数组的第0个索引中edi,mov al, [array]现在包含数组第3个索引的内存地址al将DATA置于第零个索引中mov al, [array+3].al将DATA放在第三个索引处mov [al], …什么是大小tword,oword以及yword操作数,如使用NASM/YASM手册?在相关的说明中,这些名称是否存在技巧或潜在的想法?有没有一种方法可以为更大的字大小赋予逻辑名称?
我知道,虽然字大小可以系统之间是不同的,一个NASM word是2个字节,dword是两倍(4个字节),qword是一个四字(8个字节),但是...是tword一个三重字(6个字节)?而对于oword和yword我甚至不能想象的一个似是而非的含义.
请注意,这可能是一个简单的问题,但我找不到答案.在NASM和YASM手册这些尺寸没有解释,甚至没有在DQ,DT,DY,RESQ,REST,RESY伪指令.我读到MASM使用类似系统的地方,但也找不到任何东西.
编辑:根据答案,这是完整的列表:
byteDBRESBwordDWRESWdwordDDRESDqwordDQRESQtwordDTRESToword,DO,,RESODDQRESDQywordDYRESY测试平台是32位Linux.
基本上,我知道gcc可以用来生成Intel和At&T样式的汇编代码,但似乎你不能直接使用nasm/tasm来编译生成的Intel样式汇编代码.
我正在Windows和Linux平台上进行项目分析asm代码,所以我想如果它们都可以由像nasm\yasm这样的平台独立汇编程序编译,我可以有一个更容易的时间......
所以我的问题是如何从Linux上的c源代码生成一个nasm可编译的汇编代码?
我遇到了一个奇怪的问题.我试着安装x264.运行sudo ./configure --enable-shared时,它给出了:
找不到汇编程序最低版本是yasm-0.7.0如果你真的想在没有asm的情况下编译,请使用--disable-asm进行配置.
但我已经安装了yasm-0.7.0,以证明,我运行yasm --version,它给出了:
*yasm 0.7.0.2066编译于2012年5月8日.版权所有(c)2001-2008 Peter Johnson和其他Yasm开发人员.运行yasm --license以获取许可概述和摘要.*
我将yasm安装到/ usr/local/yasm,为什么找不到yasm?
我已经使用yasm进行代码汇编,并链接到我的C++程序,但是我无法在汇编语言文件中的符号上设置gdb中的断点.
命令行可能不是非常有启发性,但我们在这里:
"g++" -ftemplate-depth-128 -O0 -fno-inline -Wall -g -fPIC -std=c++11 -I"$HOME/usr/include" -c -o "bin/gcc-4.7/debug/main.o" "main.cpp"
yasm -g dwarf2 -f elf64 -o bin/gcc-4.7/debug/mandel.o mandel.yasm
"g++" -L"$HOME/usr/lib" -Wl,-R -Wl,"$HOME/usr/lib" -Wl,-rpath-link -Wl,"$HOME/usr/lib" -o "bin/gcc-4.7/debug/mandel" -Wl,--start-group "bin/gcc-4.7/debug/main.o" "bin/gcc-4.7/debug/mandel.o" -Wl,-Bstatic -Wl,-Bdynamic -lboost_system -lboost_thread -Wl,--end-group -g
Run Code Online (Sandbox Code Playgroud)
所有构建都没有发生任何事故,程序运行.但是当我尝试将其加载到gdb中进行调试时,我似乎无法在yasm文件中的任何函数上添加断点.例如,我在那里有一个名为MandelRect的函数.这是gdb显示我在哪里调用它,在main中的某个地方:
(gdb) disassemble 0x404ada,0x404af0
Dump of assembler code from 0x404ada to 0x404af0:
0x0000000000404ada <main()+474>: mov %rax,%rdi
0x0000000000404add <main()+477>: callq 0x409980 <MandelRect>
0x0000000000404ae2 <main()+482>: movq $0x0,-0x18(%rbp)
0x0000000000404aea <main()+490>: jmp 0x404b1c <main()+540>
0x0000000000404aec <main()+492>: mov -0x18(%rbp),%rdx
End of assembler dump.
Run Code Online (Sandbox Code Playgroud)
这是gdb告诉我它的地址是什么:
(gdb) …Run Code Online (Sandbox Code Playgroud) I have a function foo written in assembly and compiled with yasm and GCC on Linux (Ubuntu) 64-bit. It simply prints a message to stdout using puts(), here is how it looks:
bits 64
extern puts
global foo
section .data
message:
db 'foo() called', 0
section .text
foo:
push rbp
mov rbp, rsp
lea rdi, [rel message]
call puts
pop rbp
ret
Run Code Online (Sandbox Code Playgroud)
It is called by a C program compiled with GCC:
extern void foo();
int main() {
foo(); …Run Code Online (Sandbox Code Playgroud) 在从书中学习汇编语言时,有一个清单显示了一些基本操作:
segment .data
a dq 176
b dq 4097
segment .text
global _start
_start:
mov rax, [a] ; Move a into rax.
add rax, [b] ; add b o rax.
xor rax, rax
ret
Run Code Online (Sandbox Code Playgroud)
使用"$yasm -f elf64 -g dwarf2 -l listing.lst listing.asm"命令组装并链接后,"$ld -o listing listing.o"我在 gdb 中运行了程序。每当我尝试打印变量的值时,gdb 都会显示以下错误消息:
(gdb) p a
'a' has unknown type; cast it to its declared type
Run Code Online (Sandbox Code Playgroud)
另一个变量“b”也是如此。但是,为 int 转换 'a' 或 'b' 有效:
(gdb) p (int)a
$11 = 176
(gdb) p …Run Code Online (Sandbox Code Playgroud) GNU 汇编器在汇编 Intel 语法代码时给出了意外的内存操作数。
我已将 bug 减少到一行代码,在过去的三天里,我尝试了一切方法来理解为什么 GNU 汇编器会产生一些我无法理解的东西。我知道这一定(或应该)是微不足道的,但我不知所措。
以下文本位于文件 code.asm 中:
.intel_syntax noprefix
.global somecode
somecode:
int 3
mov rax,qword [rcx]
ret
.att_syntax
Run Code Online (Sandbox Code Playgroud)
使用以下命令汇编和反汇编 code.asm:
as code.asm -o code1.obj -64
objdump -Mintel -d code1.obj > code1.asm
Run Code Online (Sandbox Code Playgroud)
code1.asm(带有反汇编代码)的内容是:
code1.obj: file format pe-x86-64
Disassembly of section .text:
0000000000000000 <somecode>:
0: cc int3
1: 48 8b 41 08 mov rax,QWORD PTR [rcx+0x8]
5: c3 ret
Run Code Online (Sandbox Code Playgroud)
我正在使用 GNU 汇编器 (GNU Binutils) 2.25 (`x86_64-pc-cygwin')。
问题:为什么内存操作数 QWORD PTR [rcx+0x8] 中有一个额外的 1 个 qword 偏移量(8 …
我正在研究我的代码高尔夫/二进制可执行文件的最小操作码大小x86-64 strlen实现,该实现不应该超过某个大小(为了简单起见,请考虑演示场景)。
一般想法来自这里,大小优化想法来自这里和这里。
输入字符串地址在rdi,最大长度不大于Int32
xor eax,eax ; 2 bytes
or ecx,-1 ; 3 bytes
repne scasb ; 2 bytes
not ecx ; 2 bytes
dec ecx ; 2 bytes
Run Code Online (Sandbox Code Playgroud)
最终结果是ecx在11字节总数。
问题是关于设置ecx为-1
选项 1 已经说明
or ecx,-1 ; 3 bytes
Run Code Online (Sandbox Code Playgroud)
选项 2
lea ecx,[rax-1] ; 3 bytes
Run Code Online (Sandbox Code Playgroud)
选项 3
stc ; 1 byte
sbb ecx,ecx ; 2 bytes
Run Code Online (Sandbox Code Playgroud)
选项 4 ,可能是最慢的一个
push -1 …Run Code Online (Sandbox Code Playgroud)