我试图学习汇编语言作为一种爱好,我经常用它gcc -S
来产生汇编输出.这非常简单,但我无法编译汇编输出.我只是好奇这是否可以完成.我尝试使用标准汇编输出和intel语法-masm=intel
.两者都无法编译nasm
和链接ld
.
因此,我想问一下是否可以生成汇编代码,然后可以编译.
更准确地说,我使用了以下C代码.
>> cat csimp.c
int main (void){
int i,j;
for(i=1;i<21;i++)
j= i + 100;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
生成程序集gcc -S -O0 -masm=intel csimp.c
并尝试编译nasm -f elf64 csimp.s
和链接ld -m elf_x86_64 -s -o test csimp.o
.我从nasm得到的输出读取:
csimp.s:1: error: attempt to define a local label before any non-local labels
csimp.s:1: error: parser: instruction expected
csimp.s:2: error: attempt to define a local label before any non-local labels
csimp.s:2: error: parser: …
Run Code Online (Sandbox Code Playgroud) 我正在尝试使用缓冲区溢出进行一些实验以获得乐趣.我正在这个论坛上阅读这个主题,并试着编写我自己的小代码.
所以我所做的是一个小的"C"程序,它接受字符参数并运行直到分段错误.
所以我提供参数,直到我收到一条消息,我用"A"覆盖了返回地址,这是41.我的缓冲区字符长度,我复制输入字符串是[5].
这是我在gdb中所做的.
run $(perl -e 'print "A"x32 ; ')
Program received signal SIGSEGV, Segmentation fault.
0x0000000000400516 in main (argc=Cannot access memory at address 0x414141414141412d
Run Code Online (Sandbox Code Playgroud)
然后我发现需要16'A'才能覆盖.
run $(perl -e 'print "A"x16 . "C"x8 . "B"x32 ; ')
0x0000000000400516 in main (argc=Cannot access memory at address 0x434343434343432f
)
Run Code Online (Sandbox Code Playgroud)
这告诉我们8"C"正在覆盖返回地址.
根据在线教程,如果我提供有效的地址而不是8"C".我可以跳到某个地方并执行代码.所以我在最初的16"A"之后重载了内存.
下一步是执行
run $(perl -e 'print "A"x16 . "C"x8 . "B"x200 ; ')
rax 0x0 0
rbx 0x3a0001bbc0 249108216768
rcx 0x3a00552780 249113683840
rdx 0x3a00553980 249113688448
rsi 0x42 66
rdi 0x2af9e57710e0 47252785008864 …
Run Code Online (Sandbox Code Playgroud) 我正在尝试学习如何对截短的分布进行采样。首先,我决定尝试一个简单的示例,在这里找到示例
我不太了解CDF的划分方式,因此我决定稍微调整一下算法。被采样是值的指数分布x>0
这是一个示例python代码:
# Sample exponential distribution for the case x>0
import numpy as np
import matplotlib.pyplot as plt
from scipy.stats import norm
def pdf(x):
return x*np.exp(-x)
xvec=np.zeros(1000000)
x=1.
for i in range(1000000):
a=x+np.random.normal()
xs=x
if a > 0. :
xs=a
A=pdf(xs)/pdf(x)
if np.random.uniform()<A :
x=xs
xvec[i]=x
x=np.linspace(0,15,1000)
plt.plot(x,pdf(x))
plt.hist([x for x in xvec if x != 0],bins=150,normed=True)
plt.show()
Run Code Online (Sandbox Code Playgroud)
上面的代码似乎仅在使用条件if a > 0. :
(即正数)时有效x
,选择其他条件(例如if a > 0.5 :
)会产生错误的结果。
由于我的最终目标是在截短的间隔内采样2D-Gaussian-pdf,因此我尝试使用指数分布扩展简单示例(请参见下面的代码)。不幸的是,由于这种简单的情况不起作用,因此我认为下面给出的代码将产生错误的结果。
我认为所有这些都可以使用python的高级工具完成。但是,由于我的主要想法是理解背后的原理,非常感谢您帮助我理解我的错误。谢谢您的帮助。
编辑: …
嗨,我使用Fortran 90代码来调用C函数.由于我在操作地址,因此应该在Fortran中正确匹配C函数的参数.我正在使用ifort和icc来编译代码并在64位机器上工作.
一些测试显示,这也将起作用int32_t
,虽然为了防止最终的陷阱,我想保留uint32_t
我调用的C函数有以下原型
uint32_t encode_(uint32_t x, uint32_t y)
uint32_t decode_(uint32_t dec)
Run Code Online (Sandbox Code Playgroud)
我不能仅仅通过做类似的事情来调用这些函数
integer :: cod,encode
cod = encode(i,j)
Run Code Online (Sandbox Code Playgroud)
这会产生胡言乱语.因此我使用了一种解决方法:
void code2d_(uint32_t j[] ){
uint32_t i;
i=encode_(j[0],j[1]);
// the underscore is due to the FORTRAN naming convention
printf("Coded %10d \n",i);
}
Run Code Online (Sandbox Code Playgroud)
随后在Fortran
integer :: cod,code2d
cod = code2d(i,j)
Run Code Online (Sandbox Code Playgroud)
显然我对参数类型的不匹配有一些问题.不幸的是我不知道如何解决这个问题.因为在我的解码/编码函数中完成二进制地址算术,所以保留它是非常重要的uint32_t
.