我在汇编语言中有一个问题,我必须访问数组的元素...假设一个数组包含星期几天...像sun,mon,tues,wed ....我必须访问数组的第二个索引... 我怎样才能做到这一点?
在我的一次采访中,我在一个'新的'原始集合中遇到了一个非常复杂的问题(当他们告诉我他们基于Python的QA测试时,为什么地狱QA需要汇编知识?),这就是这样的:
假设您的汇编语言仅包含以下说明:
'inc REG':将给定寄存器递增1.'dec REG':将给定的寄存器减1.'jnz LABEL':如果前一条指令的结果不为零,则跳转到给定的LABEL.'HELT':停止运行.任务:A和B寄存器保持非负值.程序应计算A*B的值并将结果定位在C.此外,语言包含寄存器C,D,...,Z,您可以假设它们在程序开始时被初始化为零.
这里有几点需要更多关注,比如你必须事先考虑A和\或B值可能为零..并且多个零是......零...这真是该死的...
PS因为这个问题我没有达到'my_atoi()'问题的实现.. :-(
谢谢 !
我目前正在尝试学习汇编语言.但我被卡住了.假设我有这个C代码:
for ( int i = 100; i > 0; i-- ) {
// Some code
}
Run Code Online (Sandbox Code Playgroud)
现在我想用汇编语言做同样的事情.我试过这样的:
__asm__ ("movq $100, %rax;"
".loop:"
//Some code
"decq %rax;"
"cmpq $0, (%rax);"
"jnz .loop;"
);
Run Code Online (Sandbox Code Playgroud)
编译并运行seg故障.如果我删除cmpq行,它不会出错.但当然程序不会终止.
所以基本上我的问题是我在这里做错了什么?
提前致谢.
我想创建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) 我愿意编写一个代码,让我的CPU执行一些操作,看看他花了多少时间来解决它们.我想做一个从i = 0到i <5000的循环,然后将i乘以一个常数和时间.我最终得到了这个代码,它没有错误,但即使我更改循环i <49058349083或者如果i <2它需要相同的时间,它只需要0.024秒来执行代码.是什么错误?
PD:我昨天开始学习C++我很抱歉,如果这是一个非常容易回答的问题,但我找不到解决方案
#include <iostream>
#include <ctime>
using namespace std;
int main () {
int start_s=clock();
int i;
for(i=0;i<5000;i++){
i*434243;
}
int stop_s=clock();
cout << "time: "<< (stop_s-start_s)/double(CLOCKS_PER_SEC)*1000;
return 0;
}
Run Code Online (Sandbox Code Playgroud) 我在IvyBridge上.我发现jnz内循环和外循环中的性能行为不一致.
以下简单程序有一个固定大小为16的内部循环:
global _start
_start:
mov rcx, 100000000
.loop_outer:
mov rax, 16
.loop_inner:
dec rax
jnz .loop_inner
dec rcx
jnz .loop_outer
xor edi, edi
mov eax, 60
syscall
Run Code Online (Sandbox Code Playgroud)
perf工具显示外循环运行32c/iter.它表明jnz需要2个周期才能完成.
然后我在Agner的指令表中搜索,条件跳转有1-2"倒数吞吐量",注释"如果没有跳转就快".
在这一点上,我开始相信上述行为是以某种方式预期的.但为什么jnz在外循环中只需要1个循环来完成?
如果我.loop_inner完全删除部件,外部循环运行1c/iter.行为看起来不一致.
我在这里缺少什么?
perf上述程序的结果带命令:
perf stat -ecycles,branches,branch-misses,lsd.uops,uops_issued.any -r4 ./a.out
Run Code Online (Sandbox Code Playgroud)
是:
3,215,921,579 cycles ( +- 0.11% ) (79.83%)
1,701,361,270 branches ( +- 0.02% ) (80.05%)
19,212 branch-misses # 0.00% of all branches ( +- 17.72% ) (80.09%)
31,052 lsd.uops ( …Run Code Online (Sandbox Code Playgroud) 出于兴趣,我想在机器代码中编写一个小程序.
我目前正在学习寄存器,ALU,总线和内存,我有点着迷,指令可以用二进制而不是汇编语言编写.
是否需要使用编译器?
最好是在OSX上运行的.
(如果是这样的话,我会自己做的.)
我的问题:
为方便起见,我倾向于避免间接/索引寻址模式.
作为替代,我经常使用立即,绝对或寄存器寻址.
代码:
; %esi has the array address. Say we iterate a doubleword (4bytes) array.
; %ecx is the array elements count
(0x98767) myloop:
... ;do whatever with %esi
add $4, %esi
dec %ecx
jnz 0x98767;
Run Code Online (Sandbox Code Playgroud)
在这里,我们有一个序列化的组合(dec和jnz),它可以防止正常的乱序执行(依赖).
有没有办法避免/破坏dep?(我不是装配专家).
我在llvm clang Apple LLVM 8.0.0版(clang-800.0.42.1)上反汇编代码:
int main() {
float a=0.151234;
float b=0.2;
float c=a+b;
printf("%f", c);
}
Run Code Online (Sandbox Code Playgroud)
我编译时没有-O规范,但我也试过-O0(给出相同)和-O2(实际上计算值并存储它预先计算)
产生的反汇编如下(我删除了不相关的部分)
-> 0x100000f30 <+0>: pushq %rbp
0x100000f31 <+1>: movq %rsp, %rbp
0x100000f34 <+4>: subq $0x10, %rsp
0x100000f38 <+8>: leaq 0x6d(%rip), %rdi
0x100000f3f <+15>: movss 0x5d(%rip), %xmm0
0x100000f47 <+23>: movss 0x59(%rip), %xmm1
0x100000f4f <+31>: movss %xmm1, -0x4(%rbp)
0x100000f54 <+36>: movss %xmm0, -0x8(%rbp)
0x100000f59 <+41>: movss -0x4(%rbp), %xmm0
0x100000f5e <+46>: addss -0x8(%rbp), %xmm0
0x100000f63 <+51>: movss %xmm0, -0xc(%rbp)
...
Run Code Online (Sandbox Code Playgroud)
显然它正在做以下事情:
我有一个带有4个HT内核(8个逻辑CPU)的Intel CPU,并构建了两个简单的进程。
第一个:
int main()
{
for(int i=0;i<1000000;++i)
for(int j=0;j<100000;++j);
}
Run Code Online (Sandbox Code Playgroud)
第二个:
int main()
{
while(1);
}
Run Code Online (Sandbox Code Playgroud)
两者都编译时gcc没有特殊选项。(即默认值为-O0:无优化调试模式,将变量保留在内存中而不是寄存器中。)
当我在第一个逻辑CPU(CPU0)上运行第一个时,并且当其他逻辑CPU的负载费用接近0%时,此第一个进程的执行时间为:
real 2m42,625s
user 2m42,485s
sys 0m0,070s
Run Code Online (Sandbox Code Playgroud)
但是,当我在CPU4上运行第二个进程(无限循环)时(CPU0和CPU4在同一内核上,但不在同一硬件线程上),第一个进程的执行时间为
real 2m25,412s
user 2m25,291s
sys 0m0,047s
Run Code Online (Sandbox Code Playgroud)
我期望更长的时间,因为在同一核心上有两个进程,而不是只有一个。但这实际上更快。为什么会这样?
编辑:P状态驱动程序是intel_pstate。使用来固定C状态processor.max_cstate=1 intel_idle.max_cstate=0。将调速器设置为性能(cpupower frequency-set -g performance),禁用涡轮增压(cat /sys/devices/system/cpu/intel_pstate/no_turbo给出1)
assembly ×7
x86 ×3
x86-64 ×3
c ×2
performance ×2
benchmarking ×1
c++ ×1
fasm ×1
intel ×1
linux ×1
llvm-codegen ×1
loops ×1
machine-code ×1