- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我在阅读汇编方面变得越来越熟练,但现在我正处于需要将我的理解与实际构建 C 伪代码联系起来的阶段。作为作业的一部分,我已经注释掉了整个段落,并添加了我认为下面发生的内容。 我已经基本完成了这里的工作。我只是需要一些帮助来验证我的理解并确保我的解释是正确的。
804990f: ba 94 ae 04 08 mov $0x804ae94,%edx // this, on gdb is actually %d %d %d
8049914: 8b 45 08 mov 0x8(%ebp),%eax // function argument - parameter1 - being loaded into the eax to be considered
8049917: 8d 4d e0 lea -0x20(%ebp),%ecx // local pointer being loaded into the ecx register
804991a: 89 4c 24 10 mov %ecx,0x10(%esp) // this local pointer is now being added to the stack
804991e: 8d 4d e4 lea -0x1c(%ebp),%ecx // local pointer being loaded into the ecx register
8049921: 89 4c 24 0c mov %ecx,0xc(%esp) // this local pointer is now being added to the stack
8049925: 8d 4d e8 lea -0x18(%ebp),%ecx // local pointer being loaded into the ecx register
8049928: 89 4c 24 08 mov %ecx,0x8(%esp) // this local pointer is now being added to the stack
804992c: 89 54 24 04 mov %edx,0x4(%esp) // the three "d d d" is now also being moved to another area at the top of the stack
8049930: 89 04 24 mov %eax,(%esp) // the value of parameter one is now being treated as a pointer because address is being loaded in
8049933: e8 38 f3 ff ff call 8048c70 <sscanf@plt> // the scan function is now being called, to take in three values we passed into the array
8049938: 83 f8 03 cmp $0x3,%eax // it is comparing the parameter value which is now in the array(array[0]) to the constant 3
804993b: 74 05 je 8049942 <level_3+0x39> // if the parameter is == to 3, it jumps. so it should be like if (greater/less than)
804993d: e8 10 fa ff ff call 8049352 <call_function> // if it is not meeting these conditions, call this function
8049942: c7 45 f4 00 00 00 00 movl $0x0,-0xc(%ebp) // move the constant 0 into a local variable x
8049949: 8b 45 e8 mov -0x18(%ebp),%eax // move array[2] into the register
804994c: 89 45 f0 mov %eax,-0x10(%ebp) // move this value into a new local variable, possible something like y = array[2];
804994f: eb 08 jmp 8049959 <level_3+0x50>
8049951: 83 45 f4 01 addl $0x1,-0xc(%ebp) // add 1 to x so x = 1
8049955: 83 45 f0 04 addl $0x4,-0x10(%ebp) // add the constant 4 to y so y += 4;
8049959: 8b 45 e4 mov -0x1c(%ebp),%eax // move array[1] into the register
804995c: 39 45 f0 cmp %eax,-0x10(%ebp) // compare array[1] to y.
804995f: 7c f0 jl 8049951 <level_3+0x48> // jump if it array[1] is less than y
8049961: 83 7d f4 03 cmpl $0x3,-0xc(%ebp) // compare this number 3 into the local variable x
8049965: 74 05 je 804996c <level_3+0x63> // jump if they are equal to one another
8049967: e8 e6 f9 ff ff call 8049352 <call_function> // if it is not meeting these conditions, call function
804996c: c7 45 f4 8c 00 00 00 movl $0x8c,-0xc(%ebp) // move the constant 140 into the local variable x
8049973: 8b 45 e4 mov -0x1c(%ebp),%eax // move array[1] into the register
8049976: 85 c0 test %eax,%eax // test this value against itself
8049978: 75 05 jne 804997f <level_3+0x76> // if it is not equal, jump
804997a: e8 d3 f9 ff ff call 8049352 <call_function> // if it is not meeting these conditions, call function
804997f: c7 45 ec 08 00 00 00 movl $0x8,-0x14(%ebp) // move the number 8 into the local variable z
8049986: eb 30 jmp 80499b8 <level_3+0xaf> // jump down and leave the function
8049988: 8b 45 e8 mov -0x18(%ebp),%eax // move arr[1] into the register
804998b: 83 e8 08 sub $0x8,%eax // subtract 8 from arr[1]
804998e: 89 45 e8 mov %eax,-0x18(%ebp) // make this is the new arr[1] value
8049991: 83 7d f4 00 cmpl $0x0,-0xc(%ebp) // compare this number 0 to the local variable x
8049995: 75 17 jne 80499ae <level_3+0xa5> // if it is not equal, then jump down to the subtraction (subl below)
8049997: 8b 45 e0 mov -0x20(%ebp),%eax // move arr[0] into the register
804999a: c1 f8 02 sar $0x2,%eax // multiply by 4 (shifting it by 2 ^ 2)
804999d: 3b 45 ec cmp -0x14(%ebp),%eax // now move the variable z into the register
80499a0: 74 05 je 80499a7 <level_3+0x9e> // if it is equal, then jump down
80499a2: e8 ab f9 ff ff call 8049352 <call_function> // if these conditions are not met, call_function
80499a7: b8 00 00 00 00 mov $0x0,%eax // move the constant 0 into the register
80499ac: eb 1a jmp 80499c8 <level_3+0xbf> // jump down and leave the function
80499ae: 83 6d f4 07 subl $0x7,-0xc(%ebp) // from x subtract 7
80499b2: 8b 45 e4 mov -0x1c(%ebp),%eax // move array[1] into the register
80499b5: 01 45 ec add %eax,-0x14(%ebp) // now add this to the variable z. so z += array[1];
80499b8: 83 7d ec 07 cmpl $0x7,-0x14(%ebp) // compare the number 7 and the variable z
80499bc: 7f ca jg 8049988 <level_3+0x7f> // if it greater, then jump down
80499be: e8 8f f9 ff ff call 8049352 <call_function> // if these conditions are not met, call_function
80499c3: b8 00 00 00 00 mov $0x0,%eax // move the constant 0 into the register
80499c8: c9 leave // leave the function
80499c9: c3 ret // return the value
我的理解:
有一个参数(一个指针,在我的注释中被解释为一个数组)传递到局部变量 int array[] 中。然后在此过程中对其与一些不同的常量进行一系列比较。
我认为这是一个 while 循环,它在循环时不断检查某些递增的条件。我只是不确定如何得出这个条件是什么?
假设上面的注释是正确的,我将如何生成正确的伪代码?
最佳答案
好吧,如果注释正确,您需要弄清楚哪些指令是机器执行其业务(例如,行8049914
到804993b
,只是加载sscanf
的 args;在 C 中,它转换为
int *array[3];
int return_value = sscanf(param1, "%d %d %d", array[0], array[1], array[2]);
if(return_value == 3): // If there were 3 integers... see sscanf documentation
...
通过一些线索你可以弄清楚很多事情。例如,我们现在知道函数原型(prototype)大致如下:
level_3(char* param1 ...);
因为我们知道 sscanf
的原型(prototype):
int sscanf ( const char * s, const char * format, ...);
此外,请记住 %eax
寄存器保存被调用函数(在本例中为 sscanf
)的返回值的规则,因此比较基本上是检查是否或not param1
中有 3 个整数。此外,移动到 %esp
的某个偏移量是为要调用的函数设置参数; -%ebp
用于局部变量,+%ebp
用于函数自身的参数。
这是解码汇编时使用的推理类型的示例。您大致知道堆栈是什么样子:
________
|params... //<--- ebp
|...
|saved caller instruction pointer (%eip) // These might be mixed up
|saved caller return location on stack (%ebp)
|locals...
|...
|space that could be used for a called functions's args //<--- esp
解码汇编的关键是弄清楚mov
、lea
等如何翻译成C;毕竟,伪代码不会与寄存器混在一起。
关于c - 学习汇编——全部注释掉,需要生成伪代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24993938/
我正在尝试用 C 语言编写一个使用 gstreamer 的 GTK+ 应用程序。 GTK+ 需要 gtk_main() 来执行。 gstreamer 需要 g_main_loop_run() 来执行。
我已经使用 apt-get 安装了 opencv。我得到了以下版本的opencv2,它工作正常: rover@rover_pi:/usr/lib/arm-linux-gnueabihf $ pytho
我有一个看起来像这样的 View 层次结构(基于其他答案和 Apple 的使用 UIScrollView 的高级 AutoLayout 指南): ScrollView 所需的2 个步骤是: 为 Scr
我尝试安装 udev。 udev 在 ./configure 期间给我一个错误 --exists: command not found configure: error: pkg-config and
我正在使用 SQLite 3。我有一个表,forums,有 150 行,还有一个表,posts,有大约 440 万行。每个帖子都属于一个论坛。 我想从每个论坛中选择最新帖子的时间戳。如果我使用 SEL
使用 go 和以下包: github.com/julienschmidt/httprouter github.com/shwoodard/jsonapi gopkg.in/mgo.v2/bson
The database仅包含 2 个表: 钱包(100 万行) 事务(1500 万行) CockroachDB 19.2.6 在 3 台 Ubuntu 机器上运行 每个 2vCPU 每个 8GB R
我很难理解为什么在下面的代码中直接调用 std::swap() 会导致编译错误,而使用 std::iter_swap 编译却没有任何错误. 来自 iter_swap() versus swap() -
我有一个非常简单的 SELECT *用 WHERE NOT EXISTS 查询条款。 SELECT * FROM "BMAN_TP3"."TT_SPLDR_55E63A28_59358" SELECT
我试图按部分组织我的 .css 文件,我需要从任何文件访问文件组中的任何类。在 Less 中,我可以毫无问题地创建一个包含所有文件导入的主文件,并且每个文件都导入主文件,但在 Sass 中,我收到一个
Microsoft.AspNet.SignalR.Redis 和 StackExchange.Redis.Extensions.Core 在同一个项目中使用。前者需要StackExchange.Red
这个问题在这里已经有了答案: Updating from Rails 4.0 to 4.1 gives sass-rails railties version conflicts (4 个答案) 关
我们有一些使用 Azure DevOps 发布管道部署到的现场服务器。我们已经使用这些发布管道几个月了,没有出现任何问题。今天,我们在下载该项目的工件时开始出现身份验证错误。 部署组中的节点显示在线,
Tip: instead of creating indexes here, run queries in your code – if you're missing any indexes, you
你能解释一下 Elm 下一个声明中的意思吗? (=>) = (,) 我在 Elm architecture tutorial 的例子中找到了它 最佳答案 这是中缀符号。实际上,这定义了一个函数 (=>
我需要一个 .NET 程序集查看器,它可以显示低级详细信息,例如元数据表内容等。 最佳答案 ildasm 是 IL 反汇编程序,具有低级托管元数据 token 信息。安装 Visual Studio
我有两个列表要在 Excel 中进行比较。这是一个很长的列表,我需要一个 excel 函数或 vba 代码来执行此操作。我已经没有想法了,因此转向你: **Old List** A
Closed. This question does not meet Stack Overflow guidelines。它当前不接受答案。 想要改善这个问题吗?更新问题,以便将其作为on-topi
我正在学习 xml 和 xml 处理。我无法很好地理解命名空间的存在。 我了解到命名空间帮助我们在 xml 中分离相同命名的元素。我们不能通过具有相同名称的属性来区分元素吗?为什么命名空间很重要或需要
我搜索了 Azure 文档、各种社区论坛和 google,但没有找到关于需要在公司防火墙上打开哪些端口以允许 Azure 所有组件(blob、sql、compute、bus、publish)的简洁声明
我是一名优秀的程序员,十分优秀!